From 9abd6c818b68e066ad09e43ff8cb0dabafa9f2fe Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 31 Mar 2023 15:44:59 +0300 Subject: [PATCH 01/90] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20security-util=20=D1=81=20UserRoleVerification=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B0=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/pom.xml | 1 + clearing-parent/security-util/pom.xml | 142 ++++++++++++++++++ .../util/security/UserRoleVerification.java | 86 +++++++++++ 3 files changed, 229 insertions(+) create mode 100644 clearing-parent/security-util/pom.xml create mode 100644 clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java diff --git a/clearing-parent/pom.xml b/clearing-parent/pom.xml index 06fb06d46..f90ee465d 100644 --- a/clearing-parent/pom.xml +++ b/clearing-parent/pom.xml @@ -20,6 +20,7 @@ classes backend-api imdg + security-util db-scripts dbf-importer dbf-exporter diff --git a/clearing-parent/security-util/pom.xml b/clearing-parent/security-util/pom.xml new file mode 100644 index 000000000..2c0a2dbf5 --- /dev/null +++ b/clearing-parent/security-util/pom.xml @@ -0,0 +1,142 @@ + + + 4.0.0 + + security-util + Clearing misc util for verify user roles + jar + SPCEX-1.0.0.0 + + + clearing-parent + ru.spcex.clearing + SPCEX-1.0.0.0 + + + + 17 + 17 + + + + + org.springframework + spring-core + provided + + + org.springframework + spring-context + provided + + + ru.spcex.clearing + classes + SPCEX-1.0.0.0 + compile + + + ru.spcex.clearing + dictionary + SPCEX-1.0.0.0 + compile + + + ru.spcex.platform + platform-enum + + + + + ru.spcex.platform + platform-imdg-api + + + + org.slf4j + slf4j-api + 1.7.33 + + + + + org.springframework + spring-test + test + + + org.skyscreamer + jsonassert + test + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + + + + src/main/resources + + application.properties + + false + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + ru.spcex.clearing.imdg.IMDGApplication + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + true + ${project.artifactId} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.21.0 + + + org.junit.platform + junit-platform-surefire-provider + 1.2.0-M1 + + + org.junit.jupiter + junit-jupiter-engine + 5.2.0-M1 + + + + + + \ No newline at end of file diff --git a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java new file mode 100644 index 000000000..89b2c10d0 --- /dev/null +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -0,0 +1,86 @@ +package ru.spcex.clearing.util.security; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.objects.BusinessObject; +import ru.clearing.classes.statics.data.company.CompanyRoleSet; +import ru.clearing.classes.statics.data.user.User; +import ru.clearing.classes.statics.data.user.UserRoleSession; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.enumeration.Status; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.IEnumKey; + +import java.util.Collection; + +/** + * Проверка дополнительных прав пользователя. + *

+ * Основная проверка прав осуществляется на frontend-api, и использовать этот компонент дополнительно не требуется. + */ +@Service +public class UserRoleVerification { + protected Logger log = LoggerFactory.getLogger(getClass()); + + protected Imdg users; + protected Imdg userRoleSessions; + protected Imdg companyRoleSet; + + @Autowired + public UserRoleVerification(ImdgProvider imdg) { + userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); + companyRoleSet = imdg.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); + } + + public boolean userHasRole(Long userId, String userRole) { + String query = String.format("userId=%s and userRole=%s and status=%s", + userId, userRole, Status.Active.getKey()); + Collection roles = userRoleSessions.getCollectionIdsBySQL(query); + log.trace("userHasRole: found {} roles by query: {}", roles.size(), query); + if (roles.isEmpty()) + return false; + //todo impl, use userRoleSessions + return true; + } + + public boolean userHasRole(Long userId, Long companyId, String userRole) { + String query = String.format("userId=%s and companyId=%s and userRole=%s and status=%s", + userId, companyId, userRole, Status.Active.getKey()); + Collection roles = userRoleSessions.getCollectionIdsBySQL(query); + log.trace("userHasRole: found {} roles by query: {}", roles.size(), query); + if (roles.isEmpty()) + return false; + //todo impl, use userRoleSessions + return true; + } + + + boolean userHasRole(Long userId, IEnumKey role) { + return userHasRole(userId, role == null ? null : role.getKey()); + } + + boolean userHasRole(Long userId, Long companyId, IEnumKey role) { + return userHasRole(userId, companyId, role == null ? null : role.getKey()); + } + + boolean userHasRoleOnObject(Long userId, BusinessObject /*todo WithUserId / WithCompany */ bObject) { + //todo impl + return true; + } + + + public boolean companyHasRole(Long companyId, String companyRole) { + String query = String.format("companyId=%s and companyRole=%s and workflowStatus=%s", + companyId, companyRole, Status.Active.getKey()); + Collection roles = companyRoleSet.getCollectionIdsBySQL(query); + log.trace("companyHasRole: found {} roles by query: {}", roles.size(), query); +// if (roles.isEmpty()) return false; + //todo impl + return true; + } + + // userIsEnabled & exist - frontendapi validation +} From ead30c2765873fbd0c901766ca0f4cfc47a476c5 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 31 Mar 2023 16:13:25 +0300 Subject: [PATCH 02/90] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20clearing-utils?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/clearing-utils/pom.xml | 147 ++++++++++++++++++ .../ru/spcex/clearing/util/package-info.java | 4 + clearing-parent/pom.xml | 1 + clearing-parent/security-util/pom.xml | 1 + 4 files changed, 153 insertions(+) create mode 100644 clearing-parent/clearing-utils/pom.xml create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/package-info.java diff --git a/clearing-parent/clearing-utils/pom.xml b/clearing-parent/clearing-utils/pom.xml new file mode 100644 index 000000000..e1056c178 --- /dev/null +++ b/clearing-parent/clearing-utils/pom.xml @@ -0,0 +1,147 @@ + + + 4.0.0 + + clearing-utils + Clearing-module (classes, IMDG and other) dependency version of platform-utils + jar + SPCEX-1.0.0.0 + + + clearing-parent + ru.spcex.clearing + SPCEX-1.0.0.0 + + + + 17 + 17 + + + + + org.springframework + spring-core + provided + + + org.springframework + spring-context + provided + + + ru.spcex.clearing + classes + SPCEX-1.0.0.0 + compile + + + ru.spcex.clearing + dictionary + SPCEX-1.0.0.0 + compile + + + ru.spcex.platform + platform-enum + + + ru.spcex.platform + platform-utils + + + + + ru.spcex.platform + platform-imdg-api + + + + org.slf4j + slf4j-api + 1.7.33 + provided + + + + + org.springframework + spring-test + test + + + org.skyscreamer + jsonassert + test + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + + + + src/main/resources + + application.properties + + false + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + ru.spcex.clearing.imdg.IMDGApplication + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + true + ${project.artifactId} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.21.0 + + + org.junit.platform + junit-platform-surefire-provider + 1.2.0-M1 + + + org.junit.jupiter + junit-jupiter-engine + 5.2.0-M1 + + + + + + \ No newline at end of file diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/package-info.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/package-info.java new file mode 100644 index 000000000..636322526 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/package-info.java @@ -0,0 +1,4 @@ +/** + * Утилиты с зависимостями от множества модулей clearing-* + */ +package ru.spcex.clearing.util; \ No newline at end of file diff --git a/clearing-parent/pom.xml b/clearing-parent/pom.xml index f90ee465d..e71a79d1a 100644 --- a/clearing-parent/pom.xml +++ b/clearing-parent/pom.xml @@ -21,6 +21,7 @@ backend-api imdg security-util + clearing-utils db-scripts dbf-importer dbf-exporter diff --git a/clearing-parent/security-util/pom.xml b/clearing-parent/security-util/pom.xml index 2c0a2dbf5..c715d998a 100644 --- a/clearing-parent/security-util/pom.xml +++ b/clearing-parent/security-util/pom.xml @@ -58,6 +58,7 @@ org.slf4j slf4j-api 1.7.33 + provided From 2570b82309fa7a304b7e0b9eddd1023f912d939b Mon Sep 17 00:00:00 2001 From: ialbert Date: Fri, 31 Mar 2023 17:23:53 +0300 Subject: [PATCH 03/90] http://jira.mfd.msk:8088/browse/CLS-256 --- ...Controller.java => CompanyController.java} | 24 ++++-- .../request/cud/company/CompanyNewAction.java | 83 +++++++++++++++++++ .../company/service/CompanyService.java | 18 ++++ .../platform/messaging/domain/Consts.java | 1 + .../domain/cud/company/CompanyNewRequest.java | 56 +++++++++++++ 5 files changed, 175 insertions(+), 7 deletions(-) rename clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/{DeleteCompanyController.java => CompanyController.java} (67%) create mode 100644 clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/DeleteCompanyController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java similarity index 67% rename from clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/DeleteCompanyController.java rename to clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java index d6555064d..f75928320 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/DeleteCompanyController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java @@ -5,14 +5,14 @@ import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import ru.clearing.classes.statics.data.company.Company; 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.company.CompanyNewAction; +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.service.IOperator; @@ -26,12 +26,12 @@ import java.util.concurrent.ExecutionException; @Controller @RequestMapping("/companies") -public class DeleteCompanyController extends AbstractQueueController { +public class CompanyController extends AbstractQueueController { private final IStateLoader stateLoader; @Autowired - public DeleteCompanyController(IOperator operator, - IStateLoader stateLoader) { + public CompanyController(IOperator operator, + IStateLoader stateLoader) { super(operator); this.stateLoader = stateLoader; } @@ -57,4 +57,14 @@ public class DeleteCompanyController extends AbstractQueueController { response.fromEntity(all); return response; } + + @ApiOperation(value = "new company.") + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) + @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public CudResponse add( + @ApiParam(value = "Параметры команды в JSON формате.", required = true) + @RequestBody CompanyNewAction companyNewAction) throws ExecutionException, InterruptedException { + return processRequest(Consts.DESTINATION_COMPANY_NEW, companyNewAction); + } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java new file mode 100644 index 000000000..b44582218 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java @@ -0,0 +1,83 @@ +package ru.spcex.clearing.backendapi.controller.request.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import ru.spcex.clearing.backendapi.domain.actions.IAction; +import ru.spcex.clearing.platform.messaging.domain.ActionType; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; + +public class CompanyNewAction implements IAction { + + @ApiModelProperty(value = "Краткое наименование Компании", example = "Company Name") + @JsonProperty + private String shortName; + @ApiModelProperty(value = "Полное наименование Компании", example = "OOO Full Company Name") + @JsonProperty + private String fullName; + @ApiModelProperty(value = "Код участника торгов", example = "TRADINGCODE") + @JsonProperty + private String tradingCode; + @ApiModelProperty(value = "Код участника клиринга", example = "CLEARINGCODE") + @JsonProperty + private String clearingCode; + @ApiModelProperty(value = "Регистрационный код участника", example = "REGISTRATIONCODE") + @JsonProperty + private String registrationCode; + + @Override + public CompanyNewRequest toRequest() { + CompanyNewRequest request = new CompanyNewRequest(); + request.setShortName(this.shortName); + request.setFullName(this.fullName); + request.setTradingCode(this.tradingCode); + request.setClearingCode(this.clearingCode); + request.setRegistrationCode(this.registrationCode); + return request; + } + + @ApiModelProperty(hidden = true) + @Override + public ActionType getActionType() { + return ActionType.NEW; + } + + 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 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; + } +} 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 e9008c33d..9fa18f424 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 @@ -12,6 +12,7 @@ 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.platform.messaging.service.QueueConsumer; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -33,9 +34,26 @@ public class CompanyService extends QueueConsumer implements InitializingBean { callback(CommonDeleteRequest.class) .setConsumer(this::deleteCompany) .forDestination(Consts.DESTINATION_COMPANY_DELETE, callbacks::put); + callback(CompanyNewRequest.class) + .setConsumer(this::createCompany) + .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); init(); } + private void createCompany(BaseRequest companyNewRequestBaseRequest) { + CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); + log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); + Company company = new Company(); + company.setShortName(req.getShortName()); + company.setFullName(req.getFullName()); + company.setTradingCode(req.getTradingCode()); + company.setClearingCode(req.getClearingCode()); + company.setRegistrationCode(req.getRegistrationCode()); + companyMap.insert(company); + log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", + companyNewRequestBaseRequest.getId(), company.getId()); + } + private void deleteCompany(BaseRequest userRequest) { CommonDeleteRequest req = userRequest.getRequestPayload(); log.debug("CommonDeleteRequest received id = {}", req.getId()); 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 97ed7998a..cf5043740 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 @@ -21,6 +21,7 @@ public interface Consts { String DESTINATION_PLANNER_UPDATE = "planner-update"; String DESTINATION_PLANNER_DELETE = "planner-delete"; + String DESTINATION_COMPANY_NEW = "company-new"; String DESTINATION_COMPANY_DELETE = "company-delete"; String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update"; String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java new file mode 100644 index 000000000..a3796192e --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java @@ -0,0 +1,56 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CompanyNewRequest { + @JsonProperty + private String shortName; + @JsonProperty + private String fullName; + @JsonProperty + private String tradingCode; + @JsonProperty + private String clearingCode; + @JsonProperty + private String registrationCode; + + 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 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; + } +} From f99989145c836d20e12d82fb0e0705b5b19399e7 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 31 Mar 2023 21:40:30 +0300 Subject: [PATCH 04/90] =?UTF-8?q?=D0=A7=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BC=D0=BF=D0=B8=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BB=D0=BE=D1=81=D1=8C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/queue/AbstractControllerTest.java | 2 +- clearing-parent/clearing-utils/pom.xml | 2 +- clearing-parent/company-service/pom.xml | 12 ++++++++++++ .../clearing/util/security/UserRoleVerification.java | 6 +++--- pom.xml | 11 +++++++++++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java index 0e04e9aad..6f6e57a71 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java @@ -92,7 +92,7 @@ import static ru.spcex.clearing.backendapi.controller.utils.MatcherFactory.using BankAccountController.class, //company CompanyRoleSetController.class, - DeleteCompanyController.class, +//fixme на 31.03.2023 нет такого класса DeleteCompanyController.class, EditClearingMemberCategoryController.class, EditCompanyInfoController.class, EditCompanySymbolController.class, diff --git a/clearing-parent/clearing-utils/pom.xml b/clearing-parent/clearing-utils/pom.xml index e1056c178..e0e9bbd67 100644 --- a/clearing-parent/clearing-utils/pom.xml +++ b/clearing-parent/clearing-utils/pom.xml @@ -5,7 +5,7 @@ 4.0.0 clearing-utils - Clearing-module (classes, IMDG and other) dependency version of platform-utils + Clearing-module, dependency version of platform-utils jar SPCEX-1.0.0.0 diff --git a/clearing-parent/company-service/pom.xml b/clearing-parent/company-service/pom.xml index a34291ee8..9913e8df4 100644 --- a/clearing-parent/company-service/pom.xml +++ b/clearing-parent/company-service/pom.xml @@ -28,6 +28,18 @@ ru.spcex.clearing classes + + ru.spcex.platform + platform-enum + + + ru.spcex.clearing + security-util + + + ru.spcex.clearing + clearing-utils + org.springframework.boot spring-boot-starter diff --git a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java index 89b2c10d0..fcc2536ef 100644 --- a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -58,15 +58,15 @@ public class UserRoleVerification { } - boolean userHasRole(Long userId, IEnumKey role) { + public boolean userHasRole(Long userId, IEnumKey role) { return userHasRole(userId, role == null ? null : role.getKey()); } - boolean userHasRole(Long userId, Long companyId, IEnumKey role) { + public boolean userHasRole(Long userId, Long companyId, IEnumKey role) { return userHasRole(userId, companyId, role == null ? null : role.getKey()); } - boolean userHasRoleOnObject(Long userId, BusinessObject /*todo WithUserId / WithCompany */ bObject) { + public boolean userHasRoleOnObject(Long userId, BusinessObject /*todo WithUserId / WithCompany */ bObject) { //todo impl return true; } diff --git a/pom.xml b/pom.xml index 6a001e386..6d9c0427c 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,17 @@ ${global.project.version} + + ru.spcex.clearing + clearing-utils + ${global.project.version} + + + ru.spcex.clearing + security-util + ${global.project.version} + + ru.spcex.platform platform-classes-base From ee86ba83401d5e1ad8a4f966d0b561a9cbad5310 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 1 Apr 2023 21:41:46 +0300 Subject: [PATCH 05/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-259?= =?UTF-8?q?=20=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../queue/AbstractControllerTest.java | 2 +- .../validation/common/EnumPresentRule.java | 68 ++++++++++++++ .../validation/common/FieldRequiredRule.java | 37 ++++++++ .../company/config/BeanConfiguration.java | 14 +++ .../config/CompanyValidationConfig.java | 48 ++++++++++ .../clearing/company/error/CompanyErrors.java | 35 +++++++ .../company/service/CompanyService.java | 92 ++++++++++++++++++- .../platform/messaging/domain/Consts.java | 1 + .../utils/error/ClearingBaseException.java | 39 ++++++++ .../utils/error/ValidationException.java | 20 ++++ 10 files changed, 354 insertions(+), 2 deletions(-) create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/EnumPresentRule.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/FieldRequiredRule.java create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/BeanConfiguration.java create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/CompanyValidationConfig.java create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java create mode 100644 platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ClearingBaseException.java create mode 100644 platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ValidationException.java diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java index 6f6e57a71..d85555b9d 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java @@ -92,7 +92,7 @@ import static ru.spcex.clearing.backendapi.controller.utils.MatcherFactory.using BankAccountController.class, //company CompanyRoleSetController.class, -//fixme на 31.03.2023 нет такого класса DeleteCompanyController.class, + CompanyController.class, EditClearingMemberCategoryController.class, EditCompanyInfoController.class, EditCompanySymbolController.class, diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/EnumPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/EnumPresentRule.java new file mode 100644 index 000000000..ae05b8f70 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/EnumPresentRule.java @@ -0,0 +1,68 @@ +package ru.spcex.clearing.validation.common; + +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка поля со значением из множества (enum) + * @param Класс проверяемого объекта + * @param Enum + */ +public record EnumPresentRule(String fieldName, + Function getter, + E[] enumValues, + boolean required, + IEnumId errorWrongEnumValue, + IEnumId errorEmptyRequiredValue) implements IValidationRule> { + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param enumValues Значения из проверяемого множества (Enum.values()) + * @param required Флаг обязательности + * @param Класс проверяемого объекта + * @param Enum + */ + public static EnumPresentRule instance(String fieldName, + Function getter, + E[] enumValues, + boolean required, + IEnumId errorWrongEnumValue, + IEnumId errorEmptyRequiredValue) { + if (errorWrongEnumValue == null) throw new IllegalArgumentException("Empty errorWrongEnumValue"); + if (required && errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); + return new EnumPresentRule<>(fieldName, getter, enumValues, required, errorWrongEnumValue, errorEmptyRequiredValue); + } + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param enumValues Значения из проверяемого множества (Enum.values()) + * @param Класс проверяемого объекта + * @param Enum + */ + public static EnumPresentRule instance(String fieldName, + Function getter, + E[] enumValues, + IEnumId errorWrongEnumValue, + IEnumId errorEmptyRequiredValue) { + return new EnumPresentRule<>(fieldName, getter, enumValues, true, errorWrongEnumValue, errorEmptyRequiredValue); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + String enumCode = getter.apply(validatedObject); + if (enumCode == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty(); + for (E enumValue : enumValues) { + if (enumValue.getKey().equals(enumCode)) return empty(); + } + return of(errorWrongEnumValue, fieldName); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/FieldRequiredRule.java new file mode 100644 index 000000000..358df8caa --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/FieldRequiredRule.java @@ -0,0 +1,37 @@ +package ru.spcex.clearing.validation.common; + + +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка обязательности поля (not null) + * @param Класс проверяемого объекта + * @param Класс проверяемого значения + */ +public record FieldRequiredRule(String fieldName, Function getter, IEnumId errorEmptyRequiredValue) implements IValidationRule> { + + /** + * @param fieldName Название поля + * @param getter Метод получения значения + * @param Класс проверяемого объекта + * @param Класс проверяемого значения + */ + public static FieldRequiredRule instance(String fieldName, Function getter, IEnumId errorEmptyRequiredValue) { + if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); + return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + V value = getter.apply(validatedObject); + if (value == null) return of(errorEmptyRequiredValue, fieldName); + return empty(); + } +} 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 new file mode 100644 index 000000000..c77296e64 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/BeanConfiguration.java @@ -0,0 +1,14 @@ +package ru.spcex.clearing.company.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; + +@Configuration +public class BeanConfiguration { + @Bean + public IMessageResolver messageResolver() { + return new SimpleMessageResolver(); + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/CompanyValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/CompanyValidationConfig.java new file mode 100644 index 000000000..09e6dc2a7 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/CompanyValidationConfig.java @@ -0,0 +1,48 @@ +package ru.spcex.clearing.company.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +//import ru.spcex.clearing.validation.common.FieldRequiredRule; +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 CompanyValidationConfig { + + @Bean("companyNewRequestValidator") + public Function companyNewRequestValidator(Map> imdgForValidation) { + return companyNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(companyNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); +// addImdg.accept(IMDGDistributedNames.Map_TaskDictionary); +// addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_Company); +// addImdg.accept(IMDGDistributedNames.Map_Security); + return new ValidatorImpl<>(context + // , +// FieldRequiredRule.instance("shortName", CompanyNewRequest::getShortName, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("companySymbol", CompanyNewRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("companySymbolValue", CompanyNewRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("workflowStatus", CompanyNewRequest::getWorkflowStatus, CompanyErrors.RequiredFieldEmpty), + +// DictionaryPresentRule.instance("workflowStatus", +// CompanyNewRequest::getWorkflowStatus, +// IMDGDistributedNames.Map_WorkflowStatus, +// WorkflowStatusDictionary.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 new file mode 100644 index 000000000..1784b0f5c --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java @@ -0,0 +1,35 @@ +package ru.spcex.clearing.company.error; + +import ru.spcex.platform.utils.enumeration.IEnumId; + +public enum CompanyErrors implements IEnumId { + GeneralError(3000L), // Общая ошибка модуля company-service + UserVerifyDenial(3001L), // 'Нет прав на проведение данной операции + + RequiredFieldEmpty(3002L), // Не заданы обязательные поля %s. + DictionaryNotFound(3003L), // Запись с идентификатором %s в справочнике %s не найдена. + VrongFieldValue(3004L), // Неверное значение поля %s. + RecordAlreadyExist(3005L), // Запись с идентификатором %s уже существует. + RecordNotFound(3006L), // Запись с идентификатором %s не найдена. + CompanyALreadyExist(3010L), // Компания %s уже существует + CompanyNotFound(3011L), // Компания %s не найдена. + CompanyDisabled(3012L), // Компания %s неактивна. + ProfileNotFound(3013L), // Профиль компании %s не найден. + CompanyInfoNotFound(3014L), // Реквизит компании %s не найден. + ContactNotFound(3015L), // Контакт компании %s не найден. + CategoryNotFound(3016L), // Категория компании %s не найдена. + CategoryAlreadySet(3017L), // Компании %s уже присвоена категория %s. + CompanyAlreadyHas_(3018L), // У компании %s присутствуют обязательства. + + ; + private final Long id; + + CompanyErrors(Long id) { + this.id = id; + } + + @Override + public Long getId() { + return id; + } +} 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 9fa18f424..007058195 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 @@ -6,6 +6,7 @@ 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.spcex.clearing.imdg.IMDGDistributedNames; @@ -14,19 +15,44 @@ 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.platform.messaging.service.QueueConsumer; +//import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.platform.enumeration.*; 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.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.validation.IValidator; + +import java.time.Instant; +import java.util.Optional; +import java.util.function.Function; @Service public class CompanyService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg companyMap; + private final ImdgId idSequence; +// protected UserRoleVerification userRoleVerification; + protected IMessageResolver messageResolver; + + private Function companyNewRequestValidator; @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider) { + ImdgProvider imdgProvider, + IMessageResolver messageResolver, +// , UserRoleVerification userRoleVerification + @Qualifier("companyNewRequestValidator") + Function companyNewRequestValidator + ) { super(kafkaQueue, kafkaProducer); + this.messageResolver = messageResolver; this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.idSequence = imdgProvider.getImdgIdGenerator(); +// this.userRoleVerification = userRoleVerification; + this.companyNewRequestValidator = companyNewRequestValidator; } @Override @@ -37,23 +63,87 @@ public class CompanyService extends QueueConsumer implements InitializingBean { callback(CompanyNewRequest.class) .setConsumer(this::createCompany) .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); + callback(CompanyNewRequest.class) + .setConsumer(this::updateCompany) + .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); + //todo IV - сообщения на добавления документа расторжения договора - см. Документ расторжения договора. profileDocument): необходимо обновить запись в company согласно описанию с тэгом "При обработке расторжения". +// callback(CompanyNewRequest.class) +// .setConsumer(this::updateCompany) +// .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); init(); } + protected void validateRole(BaseRequest req) throws ValidationException { + Long requestor = null; // todo требуется передавать это значение из frontendapi! req.getUserId(); +// if (!userRoleVerification.userHasRole(requestor, UserRole.Admin)) { +// +// }; + } + + void validate(CompanyNewRequest object) throws ValidationException { + IValidator validator = companyNewRequestValidator.apply(object); + Optional error = validator.tillFirstError(); + if (error.isPresent()) { + log.warn("CompanyNewRequest validation error: {}", error.get()); + String errorMsg = messageResolver.resolve(error.get()); +// return new RequestInfoUpdate() // todo reply message +// .setId(userRequest.getId()) +// .setStatus(Status.Error) +// .setMessage(errorMsg); + } + } + private void createCompany(BaseRequest companyNewRequestBaseRequest) { CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); + try { + validateRole(companyNewRequestBaseRequest); + validate(req); + } catch (ValidationException e) { + throw new RuntimeException(e); // todo true return error + } Company company = new Company(); + company.setId(idSequence.nextId()); + Instant now = Instant.now(); + company.setCreated(now); + company.setUpdated(now); + company.setShortName(req.getShortName()); company.setFullName(req.getFullName()); company.setTradingCode(req.getTradingCode()); company.setClearingCode(req.getClearingCode()); company.setRegistrationCode(req.getRegistrationCode()); + + company.setWorkflowStatus(WorkflowStatus.Active.getKey()); +// if (WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { +// +// } else if (WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { +// +// } + companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); } + + private void updateCompany(BaseRequest companyNewRequestBaseRequest) { + //todo update +// CompanyUpdateRequest req = companyUpdateRequestBaseRequest.getRequestPayload(); +// log.debug("company-update request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); +// Company company = new Company(); +// company.setShortName(req.getShortName()); +// company.setFullName(req.getFullName()); +// company.setTradingCode(req.getTradingCode()); +// company.setClearingCode(req.getClearingCode()); +// company.setRegistrationCode(req.getRegistrationCode()); +// companyMap.insert(company); +// log.debug("company-update request processed, BaseRequest.id = {}, company.id={}", +// companyNewRequestBaseRequest.getId(), company.getId()); + } + + + private void deleteCompany(BaseRequest userRequest) { CommonDeleteRequest req = userRequest.getRequestPayload(); log.debug("CommonDeleteRequest received id = {}", req.getId()); 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 cf5043740..44d11db48 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 @@ -23,6 +23,7 @@ public interface Consts { String DESTINATION_COMPANY_NEW = "company-new"; String DESTINATION_COMPANY_DELETE = "company-delete"; + String DESTINATION_COMPANY_UPDATE = "company-update"; String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update"; String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update"; String DESTINATION_CONTACT_UPDATE = "contact-update"; diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ClearingBaseException.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ClearingBaseException.java new file mode 100644 index 000000000..6a5c0b4e0 --- /dev/null +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ClearingBaseException.java @@ -0,0 +1,39 @@ +package ru.spcex.platform.utils.error; + +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; + +import java.util.Arrays; + +public class ClearingBaseException extends Exception { + final EnumMessage enumMsg; + + public ClearingBaseException(EnumMessage msg) { + super(msg == null ? "" : msg.getSubject().getId() + " " + (msg.getArgs() == null ? "" : Arrays.toString(msg.getArgs()))); + this.enumMsg = msg; + } + + public ClearingBaseException(ErrorEnum code) { + this(new EnumMessage(code)); + } + + public ClearingBaseException(ErrorEnum code, String message) { + super(code == null ? message : code.getId() + " " + message); + this.enumMsg = new EnumMessage(code); + } + + public ClearingBaseException(ErrorEnum code, String message, Throwable cause) { + super(code == null ? message : code.getId() + " " + message, cause); + this.enumMsg = new EnumMessage(code); + } + +// public ClearingBaseException(String message, Throwable cause) { +// super(message, cause); +// this.enumMsg = new EnumMessage(ClearingError.GeneralError); +// } + + public EnumMessage getEnumMsg() { + return enumMsg; + } + +} diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ValidationException.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ValidationException.java new file mode 100644 index 000000000..06cf2901f --- /dev/null +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/error/ValidationException.java @@ -0,0 +1,20 @@ +package ru.spcex.platform.utils.error; + +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; + +public class ValidationException extends ClearingBaseException { + + public ValidationException(EnumMessage msg) { + super(msg); + } + + public ValidationException(ErrorEnum code, String... args) { + super(new EnumMessage(code, args)); + } + + public ValidationException(ErrorEnum code, String message) { + super(code, message); + } + +} From a7875f23968c980739623b75bc4ccef221cbe804 Mon Sep 17 00:00:00 2001 From: akulikov Date: Sun, 2 Apr 2023 20:29:39 +0300 Subject: [PATCH 06/90] =?UTF-8?q?=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20ClearingMemberCategor?= =?UTF-8?q?y.=20=D0=B5=D1=81=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB?= =?UTF-8?q?=D0=B5=D0=BC=D0=B0=20=D1=81=20clearing-utils,=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B5=20maven=20=D0=B5?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=BD=D0=B5=20=D0=B2=D0=B8=D0=B4=D0=B8=D1=82,?= =?UTF-8?q?=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=20=D0=B1?= =?UTF-8?q?=D1=8B=D0=BB=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/clearing-utils/pom.xml | 4 + .../common/context/IValidatorContext.java | 7 ++ .../common/context/ImdgValidationContext.java | 54 +++++++++ .../common/rules/DateNotBeforeRule.java | 61 ++++++++++ .../common/rules/DictionaryPresentRule.java | 102 ++++++++++++++++ .../common/{ => rules}/EnumPresentRule.java | 9 +- .../common/{ => rules}/FieldRequiredRule.java | 13 +- .../common/rules/IValidationRule.java | 44 +++++++ .../common/rules/IdPresentRule.java | 105 ++++++++++++++++ .../common/rules/TimeNotBeforeRule.java | 61 ++++++++++ .../common/validator/IValidator.java | 46 +++++++ .../common/validator/ValidationHelper.java | 36 ++++++ .../common/validator/ValidatorImpl.java | 113 +++++++++++++++++ ...learingMemberCategoryValidationConfig.java | 114 ++++++++++++++++++ .../config/validation/ValidationConfig.java | 30 +++++ .../clearing/company/error/CompanyErrors.java | 2 +- .../ClearingMemberCategoryService.java | 48 +++++++- .../cud/common/CommonDeleteRequest.java | 1 + .../messaging/service/QueueConsumer.java | 1 + .../utils/validation/IValidationRule.java | 1 + 20 files changed, 839 insertions(+), 13 deletions(-) create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java rename clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/{ => rules}/EnumPresentRule.java (84%) rename clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/{ => rules}/FieldRequiredRule.java (69%) create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java diff --git a/clearing-parent/clearing-utils/pom.xml b/clearing-parent/clearing-utils/pom.xml index e0e9bbd67..59e076a6b 100644 --- a/clearing-parent/clearing-utils/pom.xml +++ b/clearing-parent/clearing-utils/pom.xml @@ -86,6 +86,10 @@ assertj-core test + + ru.spcex.platform + platform-messaging + diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java new file mode 100644 index 000000000..d1003c026 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java @@ -0,0 +1,7 @@ +package ru.spcex.clearing.validation.common.context; + +public interface IValidatorContext { + default S getStoredObject(Enum storedObject) { + throw new UnsupportedOperationException("not implemented"); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java new file mode 100644 index 000000000..6e205e4eb --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java @@ -0,0 +1,54 @@ +package ru.spcex.clearing.validation.common.context; + +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; + +import java.util.HashMap; +import java.util.Map; + + +public class ImdgValidationContext implements IValidatorContext { + private final Map> imdgs; + private final Map, Object> storedObjects; + private T validatedObject; + + public ImdgValidationContext() { + this.imdgs = new HashMap<>(); + this.storedObjects = new HashMap<>(); + } + + public void addImdg(String key, Imdg imdg) { + imdgs.put(key, imdg); + } + + public void setValidatedObject(T validatedObject) { + this.validatedObject = validatedObject; + } + + public T getValidatedObject() { + return validatedObject; + } + + /** + * !!!не использовать один Enum в разных местах + */ + public void storeObject(Enum storedObject, Object anyObject) { + storedObjects.put(storedObject, anyObject); + } + + @Override + @SuppressWarnings("unchecked") + public S getStoredObject(Enum storedObject) { + Object o = storedObjects.get(storedObject); + return (S) o; + } + + @SuppressWarnings("unchecked") + public Imdg obtainMap(String mapName, Class clazz) { + Imdg imdg = imdgs.get(mapName); + if (imdg == null) { + throw new IllegalStateException(mapName + " imdg wasn't added to validation context"); + } + return (Imdg) imdg; + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java new file mode 100644 index 000000000..154275358 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java @@ -0,0 +1,61 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка поля с LocalDate. Условие проверки: поверяемая дата >= текущая дата + * @param Класс проверяемого объекта + */ +public record DateNotBeforeRule( + String fieldName, + Function getter, + IEnumId errorEmptyRequiredValue, + IEnumId errorTaskForPastDate, + boolean required +) implements IValidationRule> { + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемой даты + * @param required Флаг обязательности поля + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorTaskForPastDate Ошибка, которая будет возвращена, если проверяемая дата меньше текущей + * @param Класс проверяемого объекта + */ + public static DateNotBeforeRule instance(String fieldName, + Function getter, + IEnumId errorEmptyRequiredValue, + IEnumId errorTaskForPastDate, + boolean required) { + return new DateNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastDate, required); + } + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемой даты + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorTaskForPastDate Ошибка, которая будет возвращена, если проверяемая дата меньше текущей + * @param Класс проверяемого объекта + */ + public static DateNotBeforeRule instance(String fieldName, + Function getter, + IEnumId errorEmptyRequiredValue, + IEnumId errorTaskForPastDate) { + return new DateNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastDate, true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + LocalDate date = getter.apply(validatedObject); + if (date == null) return required ? of(errorEmptyRequiredValue, fieldName) : Optional.empty(); + if (date.isBefore(LocalDate.now())) return of(errorTaskForPastDate, fieldName); + return Optional.empty(); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java new file mode 100644 index 000000000..11d2bc0c0 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -0,0 +1,102 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.clearing.platform.dictionary.AbstractDictionary; +import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.imdg.api.Imdg; +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.IEnumId; + +import java.util.Collection; +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка поля с кодом из словаря (таблицы *_dictionary) + * @param Класс проверяемого объекта + * @param Класс словаря + */ +public record DictionaryPresentRule(String fieldName, + Function getter, + String dictionaryName, + Class dictionaryClass, + IEnumId errorEmptyRequiredValue, + IEnumId errorWrongDictionaryValue, + boolean required) implements IValidationRule> { + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param dictionaryName Название словаря (см. IMDGDistributedNames) + * @param dictionaryClass Класс словаря (классы *Dictionary.class) + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorWrongDictionaryValue Ошибка, которая будет возвращена, если поле не найдено в словаре + * @param required Флаг обязательности + * @param Класс проверяемого объекта + * @param Класс словаря + */ + public static DictionaryPresentRule instance(String fieldName, + Function getter, + String dictionaryName, + Class dictionaryClass, + IEnumId errorEmptyRequiredValue, + IEnumId errorWrongDictionaryValue, + boolean required) { + return new DictionaryPresentRule<>(fieldName, + getter, + dictionaryName, + dictionaryClass, + errorWrongDictionaryValue, + errorEmptyRequiredValue, + required); + } + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param dictionaryName Название словаря (см. IMDGDistributedNames) + * @param dictionaryClass Класс словаря (классы *Dictionary.class) + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorWrongDictionaryValue Ошибка, которая будет возвращена, если поле не найдено в словаре + * @param Класс проверяемого объекта + * @param Класс словаря + */ + public static DictionaryPresentRule instance(String fieldName, + Function getter, + String dictionaryName, + Class dictionaryClass, + IEnumId errorEmptyRequiredValue, + IEnumId errorWrongDictionaryValue) { + return new DictionaryPresentRule<>(fieldName, + getter, + dictionaryName, + dictionaryClass, + errorEmptyRequiredValue, + errorWrongDictionaryValue, + true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + String enumCode = getter.apply(validatedObject); + if (enumCode == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty(); + Imdg dictImdg = context.obtainMap( + dictionaryName, + dictionaryClass + ); + ImdgPredicateBuilder imdgPredicateBuilder = dictImdg.predicateBuilder(); + ImdgPredicate imdgPredicate = imdgPredicateBuilder.equals("code", enumCode); + Collection fromMap = dictImdg.getCollectionObjectsByPredicate(imdgPredicate); + if (fromMap.isEmpty()) { + return of(errorWrongDictionaryValue, fieldName); + } + assert fromMap.size() == 1; + D dictionaryFromMap = fromMap.iterator().next(); + if (dictionaryFromMap == null) { + return of(errorWrongDictionaryValue, fieldName); + } + return empty(); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/EnumPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java similarity index 84% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/EnumPresentRule.java rename to clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java index ae05b8f70..f32366483 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/EnumPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java @@ -1,10 +1,9 @@ -package ru.spcex.clearing.validation.common; +package ru.spcex.clearing.validation.common.rules; -import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.clearing.validation.common.context.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; import ru.spcex.platform.utils.enumeration.IEnumKey; -import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; import java.util.function.Function; @@ -25,6 +24,8 @@ public record EnumPresentRule(String fieldName, * @param fieldName Название поля * @param getter Метод получения проверяемого значения * @param enumValues Значения из проверяемого множества (Enum.values()) + * @param errorWrongEnumValue Ошибка, которая будет возвращена, если поле не найдено в Enum + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое * @param required Флаг обязательности * @param Класс проверяемого объекта * @param Enum @@ -44,6 +45,8 @@ public record EnumPresentRule(String fieldName, * @param fieldName Название поля * @param getter Метод получения проверяемого значения * @param enumValues Значения из проверяемого множества (Enum.values()) + * @param errorWrongEnumValue Ошибка, которая будет возвращена, если поле не найдено в Enum + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое * @param Класс проверяемого объекта * @param Enum */ diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java similarity index 69% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/FieldRequiredRule.java rename to clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index 358df8caa..61cfd4913 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -1,24 +1,29 @@ -package ru.spcex.clearing.validation.common; +package ru.spcex.clearing.validation.common.rules; -import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.clearing.validation.common.context.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; -import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; import java.util.function.Function; /** * Проверка обязательности поля (not null) + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое * @param Класс проверяемого объекта * @param Класс проверяемого значения */ -public record FieldRequiredRule(String fieldName, Function getter, IEnumId errorEmptyRequiredValue) implements IValidationRule> { +public record FieldRequiredRule( + String fieldName, + Function getter, + IEnumId errorEmptyRequiredValue +) implements IValidationRule> { /** * @param fieldName Название поля * @param getter Метод получения значения + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое * @param Класс проверяемого объекта * @param Класс проверяемого значения */ diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java new file mode 100644 index 000000000..93720b21b --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java @@ -0,0 +1,44 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.spcex.clearing.validation.common.context.IValidatorContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; + +import java.util.Optional; + +/** + * Правило валидации, описывающее какую ошибку возвращать и при каких условиях + * Все необходимые данные берет из контекста + * @param контекст + */ +public interface IValidationRule { + Optional validate(C context); + + /** + * для логов + */ + default String ruleName() { + return getClass().getSimpleName(); + } + + /** + * если у валидатора был вызван метод проверить все, этот метод может использоваться для более тонкой настройки + * по дефолту - выполнять проверку даже если предыдущие выполнены с ошибками + */ + default boolean runIfErrorsPresent() { + return true; + } + + //*************** методы для сокращения кода *************** + default Optional of(IEnumId error) { + return Optional.of(new EnumMessage(error)); + } + + default Optional of(IEnumId error, Object... args) { + return Optional.of(new EnumMessage(error, args)); + } + + default Optional empty() { + return Optional.empty(); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java new file mode 100644 index 000000000..c5d118461 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java @@ -0,0 +1,105 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; + +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка наличия связанного по Id объекта в базе + * @param Класс проверяемого объекта + * @param Класс связанного объекта + */ +public record IdPresentRule( + String fieldName, + Function idGetter, + String mapName, + Class mapClass, + IEnumId errorEmptyRequiredValue, + IEnumId errorIdNotPresent, + boolean required, + Function[] additionalChecks +) implements IValidationRule> { + + /** + * @param fieldName Название поля, содержащего Id + * @param idGetter Метод получения Id + * @param mapName Название мапы связанного объекта (см. IMDGDistributedNames) + * @param mapClass Класс связанного объекта + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorIdNotPresent Ошибка, которая будет возвращена, если Id не найден + * @param required Флаг обязательности + * @param additionalChecks Дополнительные проверки, которые можно провести со связанным объектом + * @param Класс проверяемого объекта + * @param Класс связанного объекта + */ + @SafeVarargs + public static IdPresentRule instance(String fieldName, + Function idGetter, + String mapName, + Class mapClass, + IEnumId errorEmptyRequiredValue, + IEnumId errorIdNotPresent, + boolean required, + Function ... additionalChecks) { + return new IdPresentRule<>(fieldName, + idGetter, + mapName, + mapClass, + errorEmptyRequiredValue, + errorIdNotPresent, + required, + additionalChecks); + } + + /** + * @param fieldName Название поля, содержащего Id + * @param idGetter Метод получения Id + * @param mapName Название мапы связанного объекта (см. IMDGDistributedNames) + * @param mapClass Класс связанного объекта + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorIdNotPresent Ошибка, которая будет возвращена, если Id не найден + * @param additionalChecks Дополнительные проверки, которые можно провести со связанным объектом + * @param Класс проверяемого объекта + * @param Класс связанного объекта + */ + @SafeVarargs + public static IdPresentRule instance(String fieldName, + Function idGetter, + String mapName, + Class mapClass, + IEnumId errorEmptyRequiredValue, + IEnumId errorIdNotPresent, + Function ... additionalChecks) { + return new IdPresentRule<>(fieldName, + idGetter, + mapName, + mapClass, + errorEmptyRequiredValue, + errorIdNotPresent, + true, + additionalChecks); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + Long id = idGetter.apply(validatedObject); + if (id == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty(); + Imdg imdg = context.obtainMap(mapName, mapClass); + V fromMap = imdg.getSingleObjectByID(id); + if (fromMap == null) { + return of(errorIdNotPresent, fieldName); + } + for (Function additionalCheck : additionalChecks) { + IEnumId validationError = additionalCheck.apply(fromMap); + if (validationError != null) + return of(validationError, fieldName); + } + return empty(); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java new file mode 100644 index 000000000..2e76dda1b --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java @@ -0,0 +1,61 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; + +import java.time.LocalTime; +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка поля с LocalTime. Условие проверки: проверяемое время >= текущее время + * @param Класс проверяемого объекта + */ +public record TimeNotBeforeRule( + String fieldName, + Function getter, + IEnumId errorEmptyRequiredValue, + IEnumId errorTaskForPastTime, + boolean required +) implements IValidationRule> { + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемого времени + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorTaskForPastTime Ошибка, которая будет возвращена, если проверяемое время меньше текущего + * @param required Флаг обязательности поля + * @param Класс проверяемого объекта + */ + public static TimeNotBeforeRule instance(String fieldName, + Function getter, + IEnumId errorEmptyRequiredValue, + IEnumId errorTaskForPastTime, + boolean required) { + return new TimeNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastTime, required); + } + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемого времени + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorTaskForPastTime Ошибка, которая будет возвращена, если проверяемое время меньше текущего + * @param Класс проверяемого объекта + */ + public static TimeNotBeforeRule instance(String fieldName, + Function getter, + IEnumId errorEmptyRequiredValue, + IEnumId errorTaskForPastTime) { + return new TimeNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastTime, true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + LocalTime date = getter.apply(validatedObject); + if (date == null) return required ? of(errorEmptyRequiredValue, fieldName) : Optional.empty(); + if (date.isBefore(LocalTime.now())) return of(errorTaskForPastTime, fieldName); + return Optional.empty(); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java new file mode 100644 index 000000000..c5a9b7322 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.validation.common.validator; + + +import ru.spcex.clearing.validation.common.rules.IValidationRule; +import ru.spcex.platform.utils.enumeration.EnumMessage; + +import java.util.Collection; +import java.util.Optional; + +/** + * Валидатор, в который можно добавлять правила проверок. + * Будет выполнять их в том порядке, в котором их добавляли + */ +public interface IValidator { + /** + * метод для добавления правил валидации + * если положить правило с некорректными типами, при вызове validate будет ClassCastException + */ + void addRule(IValidationRule rule); + + /** + * если хотим добавить проверки другого валидатора
+ * они будут выполняться только если проверки этого успешно пройдены + * возвращает себя + */ + IValidator chain(IValidator anotherValidator); + + /** + * валидирует все (подходит для случаев когда проверки не полагаются на то что предыдущие проверки прошли нормально) + */ + Collection validateAll(); + + /** + * валидирует до первой ошибки + */ + Optional tillFirstError(); + + /** + * валидирует все, возвращает первую ошибку - для совместимости + */ + Optional validateAllReturnFirst(); + + default S getStored(Enum storedObject) { + throw new UnsupportedOperationException("not implemented"); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java new file mode 100644 index 000000000..9b75f02f8 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java @@ -0,0 +1,36 @@ +package ru.spcex.clearing.validation.common.validator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.Status; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IMessageResolver; + +import java.util.Optional; +import java.util.function.Function; + +public class ValidationHelper { + private final static Logger log = LoggerFactory.getLogger(ValidationHelper.class); + + public static RequestInfoUpdate validate(BaseRequest userRequest, + Function validatorBuilder, + IMessageResolver messageResolver) { + if (validatorBuilder != null) { + R req = userRequest.getRequestPayload(); + IValidator validator = validatorBuilder.apply(req); + Optional validationError = validator.tillFirstError(); + if (validationError.isPresent()) { + String errorMsg = messageResolver.resolve(validationError.get()); + log.error("validation error for {} error={}, id={}: {}", req.getClass().getSimpleName(), validationError.get().getSubject(), userRequest.getId(), errorMsg); + return new RequestInfoUpdate() + .setId(userRequest.getId()) + .setStatus(Status.Error) + .setMessage(errorMsg); + } + } + return null; + } + +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java new file mode 100644 index 000000000..f647dc909 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java @@ -0,0 +1,113 @@ +package ru.spcex.clearing.validation.common.validator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.spcex.clearing.validation.common.context.IValidatorContext; +import ru.spcex.clearing.validation.common.rules.IValidationRule; +import ru.spcex.platform.utils.enumeration.EnumMessage; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +/** + * Валидатор, предназначенный для правил у которых есть "контекст" валидации + */ +public class ValidatorImpl implements IValidator { + private final Logger log = LoggerFactory.getLogger(getClass()); + private List> rules = new ArrayList<>(); + private C context; + private IValidator chainedValidator; + + public ValidatorImpl(C context) {this.context = context;} + + public ValidatorImpl(C context, IValidationRule... rules) { // + this.context = context; + for (IValidationRule rule : rules) { + addRule(rule); + } + } + + public void setContext(C context) { + this.context = context; + } + + @Override + @SuppressWarnings("unchecked") + public void addRule(IValidationRule rule) { + rules.add((IValidationRule) rule); + } + + @Override + public IValidator chain(IValidator anotherValidator) { + if (chainedValidator == null) { + chainedValidator = anotherValidator; + } else { + chainedValidator.chain(anotherValidator); + } + return this; + } + + @Override + public Collection validateAll() { + List errors = new ArrayList<>(); + Instant begin = Instant.now(); + for (IValidationRule rule : rules) { + if (rule.runIfErrorsPresent() || errors.size() == 0) { + Optional validationError; + validationError = rule.validate(context); + validationError.ifPresent(errors::add); + if (validationError.isPresent()) { + log.debug("validating stage: {} error", rule.ruleName()); + } else { + log.debug("validating stage: {} complete", rule.ruleName()); + } + } + } + log.debug("validation {} in {} ms", + errors.size() == 0 ? "successfully completed" : "completed with errors", + Instant.now().toEpochMilli() - begin.toEpochMilli()); + if (chainedValidator != null && errors.size() == 0) errors.addAll(chainedValidator.validateAll()); + return errors; + } + + @Override + public Optional tillFirstError() { + Instant begin = Instant.now(); + for (IValidationRule rule : rules) { + log.debug("validating stage: {}", rule.ruleName()); + Optional validationError; + validationError = rule.validate(context); + if (validationError.isPresent()) { + log.debug("validation stage: {} completed with error {} in {} ms", + rule.ruleName(), validationError.get().getSubject().getId(), + Instant.now().toEpochMilli() - begin.toEpochMilli()); + return validationError; + } + } + log.debug("validation successfully completed in {} ms", Instant.now().toEpochMilli() - begin.toEpochMilli()); + if (chainedValidator != null) return chainedValidator.tillFirstError(); + return Optional.empty(); + } + + @Override + public Optional validateAllReturnFirst() { + Collection allErrors = validateAll(); + if (allErrors.size() > 0) { + EnumMessage error = allErrors.iterator().next(); + return Optional.of(error); + } else + return Optional.empty(); + } + + @Override + public S getStored(Enum storedObject) { + return context.getStoredObject(storedObject); + } + + public C getContext() { + return context; + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java new file mode 100644 index 000000000..f338757e8 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java @@ -0,0 +1,114 @@ +//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.generated.ClearingMemberCategory; +//import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +//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.ClearingMemberCategoryNewRequest; +//import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; +//import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +//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.clearing.validation.common.validator.IValidator; +//import ru.spcex.clearing.validation.common.validator.ValidatorImpl; +//import ru.spcex.platform.classes.base.SpcexObjectBase; +//import ru.spcex.platform.enumeration.ClearingCategory; +//import ru.spcex.platform.enumeration.WorkflowStatus; +//import ru.spcex.platform.imdg.api.Imdg; +// +//import java.util.Map; +//import java.util.function.Consumer; +//import java.util.function.Function; +// +//@Configuration +//public class ClearingMemberCategoryValidationConfig { +// +// @Bean("clearingMemberCategoryNewRequestValidator") +// public Function clearingMemberCategoryNewRequestValidator( +// Map> imdgForValidation +// ) { +// return clearingMemberCategoryNewRequest -> { +// ImdgValidationContext context = new ImdgValidationContext<>(); +// context.setValidatedObject(clearingMemberCategoryNewRequest); +// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); +// addImdg.accept(IMDGDistributedNames.Map_Company); +// return new ValidatorImpl<>(context, +// IdPresentRule.instance("companyId", +// ClearingMemberCategoryNewRequest::getCompanyId, +// IMDGDistributedNames.Map_Company, +// Company.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.CompanyNotFound, +// company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), +// FieldRequiredRule.instance("clearingMemberCategory", +// ClearingMemberCategoryNewRequest::getClearingMemberCategory, +// CompanyErrors.RequiredFieldEmpty)); +// }; +// } +// +// @Bean("clearingMemberCategoryUpdateRequestValidator") +// public Function clearingMemberCategoryUpdateRequestValidator( +// Map> imdgForValidation +// ) { +// return clearingMemberCategoryUpdateRequest -> { +// ImdgValidationContext context = new ImdgValidationContext<>(); +// context.setValidatedObject(clearingMemberCategoryUpdateRequest); +// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); +// addImdg.accept(IMDGDistributedNames.Map_Company); +// addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); +// return new ValidatorImpl<>(context, +// IdPresentRule.instance("id", +// ClearingMemberCategoryUpdateRequest::getId, +// IMDGDistributedNames.Map_ClearingMemberCategory, +// ClearingMemberCategory.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.CategoryNotFound, +// clearingMemberCategory -> { +// Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); +// Company company = companyImdg.getSingleObjectByID(clearingMemberCategory.getCompanyId()); +// if (company == null) return CompanyErrors.CompanyNotFound; +// if (!WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus())) +// return CompanyErrors.CompanyDisabled; +// return null; +// }), +// EnumPresentRule.instance("clearingMemberCategory", +// ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, +// ClearingCategory.values(), +// CompanyErrors.WrongFieldValue, +// CompanyErrors.RequiredFieldEmpty), +// DictionaryPresentRule.instance("clearingMemberCategory", +// ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, +// IMDGDistributedNames.Map_ClearingCategoryDictionary, +// ClearingCategoryDictionary.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.WrongFieldValue)); +// }; +// } +// +// @Bean("clearingMemberCategoryDeleteRequestValidator") +// public Function clearingMemberCategoryDeleteRequestValidator( +// Map> imdgForValidation +// ) { +// return clearingMemberCategoryDeleteRequest -> { +// ImdgValidationContext context = new ImdgValidationContext<>(); +// context.setValidatedObject(clearingMemberCategoryDeleteRequest); +// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); +// addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); +// return new ValidatorImpl<>(context, +// IdPresentRule.instance("id", +// CommonDeleteRequest::getId, +// IMDGDistributedNames.Map_ClearingMemberCategory, +// ClearingMemberCategory.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.CategoryNotFound) +// ); +// }; +// } +// +//} 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 new file mode 100644 index 000000000..e39ce71e4 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java @@ -0,0 +1,30 @@ +//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.generated.ClearingMemberCategory; +//import ru.spcex.clearing.imdg.IMDGDistributedNames; +//import ru.spcex.platform.classes.base.SpcexObjectBase; +//import ru.spcex.platform.imdg.api.Imdg; +//import ru.spcex.platform.imdg.api.ImdgProvider; +// +//import java.util.HashMap; +//import java.util.Map; +//import java.util.function.BiConsumer; +// +//@Configuration +//public class ValidationConfig { +// +// @Bean("imdgForValidation") +// public Map> imdgForValidation(ImdgProvider imdgProvider) { +// final Map> imdg = new HashMap<>(); +// BiConsumer> addImdg = (s, aClass) -> imdg.put(s, imdgProvider.getImdg(s, aClass)); +// +// addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); +// addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.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 1784b0f5c..ca3edbd16 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 @@ -8,7 +8,7 @@ public enum CompanyErrors implements IEnumId { RequiredFieldEmpty(3002L), // Не заданы обязательные поля %s. DictionaryNotFound(3003L), // Запись с идентификатором %s в справочнике %s не найдена. - VrongFieldValue(3004L), // Неверное значение поля %s. + WrongFieldValue(3004L), // Неверное значение поля %s. RecordAlreadyExist(3005L), // Запись с идентификатором %s уже существует. RecordNotFound(3006L), // Запись с идентификатором %s не найдена. CompanyALreadyExist(3010L), // Компания %s уже существует 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 869049fe8..6ca00b196 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 @@ -15,19 +15,40 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteReques 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.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.IMessageResolver; @Service public class ClearingMemberCategoryService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg clearingMemberCategoryMap; + private final IMessageResolver messageResolver; + + /* + private final Function clearingMemberCategoryNewRequestValidator; + private final Function clearingMemberCategoryUpdateRequestValidator; + private final Function clearingMemberCategoryDeleteRequestValidator; + */ + @Autowired - public ClearingMemberCategoryService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider) { + public ClearingMemberCategoryService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + IMessageResolver messageResolver /*, + @Qualifier("clearingMemberCategoryNewRequestValidator") Function clearingMemberCategoryNewRequestValidator, + @Qualifier("clearingMemberCategoryUpdateRequestValidator") Function clearingMemberCategoryUpdateRequestValidator, + @Qualifier("clearingMemberCategoryDeleteRequestValidator") Function clearingMemberCategoryDeleteRequestValidator */) { super(kafkaQueue, kafkaProducer); this.clearingMemberCategoryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + this.messageResolver = messageResolver; + /* + this.clearingMemberCategoryNewRequestValidator = clearingMemberCategoryNewRequestValidator; + this.clearingMemberCategoryUpdateRequestValidator = clearingMemberCategoryUpdateRequestValidator; + this.clearingMemberCategoryDeleteRequestValidator = clearingMemberCategoryDeleteRequestValidator; + */ } @Override @@ -44,19 +65,29 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init init(); } - private void clearingMemberCategoryNew(BaseRequest userRequest) { + private RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); + +// RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryNewRequestValidator, messageResolver); +// if (requestInfoUpdate != null) return requestInfoUpdate; + log.debug("ClearingMemberCategoryUpdateRequest received {}", userRequest.getId()); ClearingMemberCategory newCategory = new ClearingMemberCategory(); newCategory.setCompanyId(req.getCompanyId()); newCategory.setClearingMemberCategory(req.getClearingMemberCategory()); clearingMemberCategoryMap.insert(newCategory); log.debug("successfully processed, new category id {}", newCategory.getId()); + + return null; } - public void clearingMemberCategoryUpdate(BaseRequest userRequest) { + public RequestInfoUpdate clearingMemberCategoryUpdate(BaseRequest userRequest) { ClearingMemberCategoryUpdateRequest req = userRequest.getRequestPayload(); + +// RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryUpdateRequestValidator, messageResolver); +// if (requestInfoUpdate != null) return requestInfoUpdate; + log.debug("ClearingMemberCategoryUpdateRequest received"); ClearingMemberCategory clearingMemberCategory = clearingMemberCategoryMap.getSingleObjectByID(req.getId()); @@ -64,12 +95,19 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init clearingMemberCategoryMap.update(clearingMemberCategory); log.debug("successfully processed, id {}", clearingMemberCategory.getId()); + return null; } - private void clearingMemberCategoryDelete(BaseRequest userRequest) { + private RequestInfoUpdate clearingMemberCategoryDelete(BaseRequest userRequest) { CommonDeleteRequest req = userRequest.getRequestPayload(); + +// RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryDeleteRequestValidator, messageResolver); +// if (requestInfoUpdate != null) return requestInfoUpdate; + log.debug("CommonDeleteRequest received id = {}", req.getId()); ClearingMemberCategory clearingMemberCategory = clearingMemberCategoryMap.getSingleObjectByID(req.getId()); clearingMemberCategoryMap.delete(clearingMemberCategory); + + return null; } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/common/CommonDeleteRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/common/CommonDeleteRequest.java index 5ad1de612..320c4d796 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/common/CommonDeleteRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/common/CommonDeleteRequest.java @@ -7,6 +7,7 @@ public class CommonDeleteRequest implements WithId { @JsonProperty public Long id; + @Override public Long getId() { return id; } 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 ad10ca627..706b50f36 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 @@ -171,6 +171,7 @@ public class QueueConsumer implements AutoCloseable { * @param Класс проверяемого запроса * @return null если ошибок нет */ + @Deprecated public RequestInfoUpdate validate(BaseRequest userRequest, Function validatorBuilder, IMessageResolver messageResolver) { diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java index 3ad88a3f1..707751089 100644 --- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java @@ -10,6 +10,7 @@ import java.util.Optional; * Все необходимые данные берет из контекста * @param контекст */ +// todo move this to clearing-utils (or move clearing-utils public interface IValidationRule { Optional validate(C context); From b6f516d81dcf3ca04f3d8a31fd25200175913fae Mon Sep 17 00:00:00 2001 From: akulikov Date: Mon, 3 Apr 2023 11:37:51 +0300 Subject: [PATCH 07/90] remove ImdgValidationContext.java, IValidatorContext.java, IValidationRule.java, IValidator.java, ValidatorImpl.java from clearing-utils --- .../common/context/IValidatorContext.java | 7 -- .../common/context/ImdgValidationContext.java | 54 --------- .../common/rules/DateNotBeforeRule.java | 3 +- .../common/rules/DictionaryPresentRule.java | 3 +- .../common/rules/EnumPresentRule.java | 3 +- .../common/rules/FieldRequiredRule.java | 3 +- .../common/rules/IValidationRule.java | 44 ------- .../common/rules/IdPresentRule.java | 3 +- .../common/rules/TimeNotBeforeRule.java | 3 +- .../common/validator/IValidator.java | 46 ------- .../common/validator/ValidationHelper.java | 1 + .../common/validator/ValidatorImpl.java | 113 ------------------ 12 files changed, 13 insertions(+), 270 deletions(-) delete mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java delete mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java delete mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java delete mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java delete mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java deleted file mode 100644 index d1003c026..000000000 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/IValidatorContext.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.spcex.clearing.validation.common.context; - -public interface IValidatorContext { - default S getStoredObject(Enum storedObject) { - throw new UnsupportedOperationException("not implemented"); - } -} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java deleted file mode 100644 index 6e205e4eb..000000000 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/context/ImdgValidationContext.java +++ /dev/null @@ -1,54 +0,0 @@ -package ru.spcex.clearing.validation.common.context; - -import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.imdg.api.Imdg; - -import java.util.HashMap; -import java.util.Map; - - -public class ImdgValidationContext implements IValidatorContext { - private final Map> imdgs; - private final Map, Object> storedObjects; - private T validatedObject; - - public ImdgValidationContext() { - this.imdgs = new HashMap<>(); - this.storedObjects = new HashMap<>(); - } - - public void addImdg(String key, Imdg imdg) { - imdgs.put(key, imdg); - } - - public void setValidatedObject(T validatedObject) { - this.validatedObject = validatedObject; - } - - public T getValidatedObject() { - return validatedObject; - } - - /** - * !!!не использовать один Enum в разных местах - */ - public void storeObject(Enum storedObject, Object anyObject) { - storedObjects.put(storedObject, anyObject); - } - - @Override - @SuppressWarnings("unchecked") - public S getStoredObject(Enum storedObject) { - Object o = storedObjects.get(storedObject); - return (S) o; - } - - @SuppressWarnings("unchecked") - public Imdg obtainMap(String mapName, Class clazz) { - Imdg imdg = imdgs.get(mapName); - if (imdg == null) { - throw new IllegalStateException(mapName + " imdg wasn't added to validation context"); - } - return (Imdg) imdg; - } -} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java index 154275358..df682c6ea 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java @@ -1,8 +1,9 @@ package ru.spcex.clearing.validation.common.rules; -import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; import java.time.LocalDate; import java.util.Optional; diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java index 11d2bc0c0..130e3ecef 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -1,12 +1,13 @@ package ru.spcex.clearing.validation.common.rules; import ru.clearing.platform.dictionary.AbstractDictionary; -import ru.spcex.clearing.validation.common.context.ImdgValidationContext; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Collection; import java.util.Optional; diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java index f32366483..a819a26e6 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java @@ -1,9 +1,10 @@ package ru.spcex.clearing.validation.common.rules; -import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; import java.util.function.Function; diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index 61cfd4913..93473976a 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -1,9 +1,10 @@ package ru.spcex.clearing.validation.common.rules; -import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; import java.util.function.Function; diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java deleted file mode 100644 index 93720b21b..000000000 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IValidationRule.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.spcex.clearing.validation.common.rules; - -import ru.spcex.clearing.validation.common.context.IValidatorContext; -import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; - -import java.util.Optional; - -/** - * Правило валидации, описывающее какую ошибку возвращать и при каких условиях - * Все необходимые данные берет из контекста - * @param контекст - */ -public interface IValidationRule { - Optional validate(C context); - - /** - * для логов - */ - default String ruleName() { - return getClass().getSimpleName(); - } - - /** - * если у валидатора был вызван метод проверить все, этот метод может использоваться для более тонкой настройки - * по дефолту - выполнять проверку даже если предыдущие выполнены с ошибками - */ - default boolean runIfErrorsPresent() { - return true; - } - - //*************** методы для сокращения кода *************** - default Optional of(IEnumId error) { - return Optional.of(new EnumMessage(error)); - } - - default Optional of(IEnumId error, Object... args) { - return Optional.of(new EnumMessage(error, args)); - } - - default Optional empty() { - return Optional.empty(); - } -} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java index c5d118461..02db04c3e 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java @@ -1,10 +1,11 @@ package ru.spcex.clearing.validation.common.rules; -import ru.spcex.clearing.validation.common.context.ImdgValidationContext; 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.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; import java.util.function.Function; diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java index 2e76dda1b..3386c66cf 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java @@ -1,8 +1,9 @@ package ru.spcex.clearing.validation.common.rules; -import ru.spcex.clearing.validation.common.context.ImdgValidationContext; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; import java.time.LocalTime; import java.util.Optional; diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java deleted file mode 100644 index c5a9b7322..000000000 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/IValidator.java +++ /dev/null @@ -1,46 +0,0 @@ -package ru.spcex.clearing.validation.common.validator; - - -import ru.spcex.clearing.validation.common.rules.IValidationRule; -import ru.spcex.platform.utils.enumeration.EnumMessage; - -import java.util.Collection; -import java.util.Optional; - -/** - * Валидатор, в который можно добавлять правила проверок. - * Будет выполнять их в том порядке, в котором их добавляли - */ -public interface IValidator { - /** - * метод для добавления правил валидации - * если положить правило с некорректными типами, при вызове validate будет ClassCastException - */ - void addRule(IValidationRule rule); - - /** - * если хотим добавить проверки другого валидатора
- * они будут выполняться только если проверки этого успешно пройдены - * возвращает себя - */ - IValidator chain(IValidator anotherValidator); - - /** - * валидирует все (подходит для случаев когда проверки не полагаются на то что предыдущие проверки прошли нормально) - */ - Collection validateAll(); - - /** - * валидирует до первой ошибки - */ - Optional tillFirstError(); - - /** - * валидирует все, возвращает первую ошибку - для совместимости - */ - Optional validateAllReturnFirst(); - - default S getStored(Enum storedObject) { - throw new UnsupportedOperationException("not implemented"); - } -} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java index 9b75f02f8..948ce73aa 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java @@ -7,6 +7,7 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.validation.IValidator; import java.util.Optional; import java.util.function.Function; diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java deleted file mode 100644 index f647dc909..000000000 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidatorImpl.java +++ /dev/null @@ -1,113 +0,0 @@ -package ru.spcex.clearing.validation.common.validator; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import ru.spcex.clearing.validation.common.context.IValidatorContext; -import ru.spcex.clearing.validation.common.rules.IValidationRule; -import ru.spcex.platform.utils.enumeration.EnumMessage; - -import java.time.Instant; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -/** - * Валидатор, предназначенный для правил у которых есть "контекст" валидации - */ -public class ValidatorImpl implements IValidator { - private final Logger log = LoggerFactory.getLogger(getClass()); - private List> rules = new ArrayList<>(); - private C context; - private IValidator chainedValidator; - - public ValidatorImpl(C context) {this.context = context;} - - public ValidatorImpl(C context, IValidationRule... rules) { // - this.context = context; - for (IValidationRule rule : rules) { - addRule(rule); - } - } - - public void setContext(C context) { - this.context = context; - } - - @Override - @SuppressWarnings("unchecked") - public void addRule(IValidationRule rule) { - rules.add((IValidationRule) rule); - } - - @Override - public IValidator chain(IValidator anotherValidator) { - if (chainedValidator == null) { - chainedValidator = anotherValidator; - } else { - chainedValidator.chain(anotherValidator); - } - return this; - } - - @Override - public Collection validateAll() { - List errors = new ArrayList<>(); - Instant begin = Instant.now(); - for (IValidationRule rule : rules) { - if (rule.runIfErrorsPresent() || errors.size() == 0) { - Optional validationError; - validationError = rule.validate(context); - validationError.ifPresent(errors::add); - if (validationError.isPresent()) { - log.debug("validating stage: {} error", rule.ruleName()); - } else { - log.debug("validating stage: {} complete", rule.ruleName()); - } - } - } - log.debug("validation {} in {} ms", - errors.size() == 0 ? "successfully completed" : "completed with errors", - Instant.now().toEpochMilli() - begin.toEpochMilli()); - if (chainedValidator != null && errors.size() == 0) errors.addAll(chainedValidator.validateAll()); - return errors; - } - - @Override - public Optional tillFirstError() { - Instant begin = Instant.now(); - for (IValidationRule rule : rules) { - log.debug("validating stage: {}", rule.ruleName()); - Optional validationError; - validationError = rule.validate(context); - if (validationError.isPresent()) { - log.debug("validation stage: {} completed with error {} in {} ms", - rule.ruleName(), validationError.get().getSubject().getId(), - Instant.now().toEpochMilli() - begin.toEpochMilli()); - return validationError; - } - } - log.debug("validation successfully completed in {} ms", Instant.now().toEpochMilli() - begin.toEpochMilli()); - if (chainedValidator != null) return chainedValidator.tillFirstError(); - return Optional.empty(); - } - - @Override - public Optional validateAllReturnFirst() { - Collection allErrors = validateAll(); - if (allErrors.size() > 0) { - EnumMessage error = allErrors.iterator().next(); - return Optional.of(error); - } else - return Optional.empty(); - } - - @Override - public S getStored(Enum storedObject) { - return context.getStoredObject(storedObject); - } - - public C getContext() { - return context; - } -} From 5560731a36543dfc7670995c3a25449475f99cf5 Mon Sep 17 00:00:00 2001 From: akulikov Date: Mon, 3 Apr 2023 11:44:17 +0300 Subject: [PATCH 08/90] need fix clearing-utils --- .../{validator => }/ValidationHelper.java | 6 +- ...learingMemberCategoryValidationConfig.java | 228 +++++++++--------- .../CompanyValidationConfig.java | 4 +- .../config/validation/ValidationConfig.java | 60 ++--- .../ClearingMemberCategoryService.java | 25 +- 5 files changed, 161 insertions(+), 162 deletions(-) rename clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/{validator => }/ValidationHelper.java (86%) rename clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/{ => validation}/CompanyValidationConfig.java (93%) diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java similarity index 86% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java rename to clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java index 948ce73aa..910ce7795 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/validator/ValidationHelper.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.validation.common.validator; +package ru.spcex.clearing.validation.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,8 +16,8 @@ public class ValidationHelper { private final static Logger log = LoggerFactory.getLogger(ValidationHelper.class); public static RequestInfoUpdate validate(BaseRequest userRequest, - Function validatorBuilder, - IMessageResolver messageResolver) { + Function validatorBuilder, + IMessageResolver messageResolver) { if (validatorBuilder != null) { R req = userRequest.getRequestPayload(); IValidator validator = validatorBuilder.apply(req); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java index f338757e8..c73dc84b8 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java @@ -1,114 +1,114 @@ -//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.generated.ClearingMemberCategory; -//import ru.clearing.platform.dictionary.ClearingCategoryDictionary; -//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.ClearingMemberCategoryNewRequest; -//import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; -//import ru.spcex.clearing.validation.common.context.ImdgValidationContext; -//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.clearing.validation.common.validator.IValidator; -//import ru.spcex.clearing.validation.common.validator.ValidatorImpl; -//import ru.spcex.platform.classes.base.SpcexObjectBase; -//import ru.spcex.platform.enumeration.ClearingCategory; -//import ru.spcex.platform.enumeration.WorkflowStatus; -//import ru.spcex.platform.imdg.api.Imdg; -// -//import java.util.Map; -//import java.util.function.Consumer; -//import java.util.function.Function; -// -//@Configuration -//public class ClearingMemberCategoryValidationConfig { -// -// @Bean("clearingMemberCategoryNewRequestValidator") -// public Function clearingMemberCategoryNewRequestValidator( -// Map> imdgForValidation -// ) { -// return clearingMemberCategoryNewRequest -> { -// ImdgValidationContext context = new ImdgValidationContext<>(); -// context.setValidatedObject(clearingMemberCategoryNewRequest); -// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); -// addImdg.accept(IMDGDistributedNames.Map_Company); -// return new ValidatorImpl<>(context, -// IdPresentRule.instance("companyId", -// ClearingMemberCategoryNewRequest::getCompanyId, -// IMDGDistributedNames.Map_Company, -// Company.class, -// CompanyErrors.RequiredFieldEmpty, -// CompanyErrors.CompanyNotFound, -// company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), -// FieldRequiredRule.instance("clearingMemberCategory", -// ClearingMemberCategoryNewRequest::getClearingMemberCategory, -// CompanyErrors.RequiredFieldEmpty)); -// }; -// } -// -// @Bean("clearingMemberCategoryUpdateRequestValidator") -// public Function clearingMemberCategoryUpdateRequestValidator( -// Map> imdgForValidation -// ) { -// return clearingMemberCategoryUpdateRequest -> { -// ImdgValidationContext context = new ImdgValidationContext<>(); -// context.setValidatedObject(clearingMemberCategoryUpdateRequest); -// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); -// addImdg.accept(IMDGDistributedNames.Map_Company); -// addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); -// return new ValidatorImpl<>(context, -// IdPresentRule.instance("id", -// ClearingMemberCategoryUpdateRequest::getId, -// IMDGDistributedNames.Map_ClearingMemberCategory, -// ClearingMemberCategory.class, -// CompanyErrors.RequiredFieldEmpty, -// CompanyErrors.CategoryNotFound, -// clearingMemberCategory -> { -// Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); -// Company company = companyImdg.getSingleObjectByID(clearingMemberCategory.getCompanyId()); -// if (company == null) return CompanyErrors.CompanyNotFound; -// if (!WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus())) -// return CompanyErrors.CompanyDisabled; -// return null; -// }), -// EnumPresentRule.instance("clearingMemberCategory", -// ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, -// ClearingCategory.values(), -// CompanyErrors.WrongFieldValue, -// CompanyErrors.RequiredFieldEmpty), -// DictionaryPresentRule.instance("clearingMemberCategory", -// ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, -// IMDGDistributedNames.Map_ClearingCategoryDictionary, -// ClearingCategoryDictionary.class, -// CompanyErrors.RequiredFieldEmpty, -// CompanyErrors.WrongFieldValue)); -// }; -// } -// -// @Bean("clearingMemberCategoryDeleteRequestValidator") -// public Function clearingMemberCategoryDeleteRequestValidator( -// Map> imdgForValidation -// ) { -// return clearingMemberCategoryDeleteRequest -> { -// ImdgValidationContext context = new ImdgValidationContext<>(); -// context.setValidatedObject(clearingMemberCategoryDeleteRequest); -// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); -// addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); -// return new ValidatorImpl<>(context, -// IdPresentRule.instance("id", -// CommonDeleteRequest::getId, -// IMDGDistributedNames.Map_ClearingMemberCategory, -// ClearingMemberCategory.class, -// CompanyErrors.RequiredFieldEmpty, -// CompanyErrors.CategoryNotFound) -// ); -// }; -// } -// -//} +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.generated.ClearingMemberCategory; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +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.ClearingMemberCategoryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; +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.ClearingCategory; +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 ClearingMemberCategoryValidationConfig { + + @Bean("clearingMemberCategoryNewRequestValidator") + public Function clearingMemberCategoryNewRequestValidator( + Map> imdgForValidation + ) { + return clearingMemberCategoryNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(clearingMemberCategoryNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + ClearingMemberCategoryNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound, + company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), + FieldRequiredRule.instance("clearingMemberCategory", + ClearingMemberCategoryNewRequest::getClearingMemberCategory, + CompanyErrors.RequiredFieldEmpty)); + }; + } + + @Bean("clearingMemberCategoryUpdateRequestValidator") + public Function clearingMemberCategoryUpdateRequestValidator( + Map> imdgForValidation + ) { + return clearingMemberCategoryUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(clearingMemberCategoryUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + ClearingMemberCategoryUpdateRequest::getId, + IMDGDistributedNames.Map_ClearingMemberCategory, + ClearingMemberCategory.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CategoryNotFound, + clearingMemberCategory -> { + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyImdg.getSingleObjectByID(clearingMemberCategory.getCompanyId()); + if (company == null) return CompanyErrors.CompanyNotFound; + if (!WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus())) + return CompanyErrors.CompanyDisabled; + return null; + }), + EnumPresentRule.instance("clearingMemberCategory", + ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, + ClearingCategory.values(), + CompanyErrors.WrongFieldValue, + CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("clearingMemberCategory", + ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue)); + }; + } + + @Bean("clearingMemberCategoryDeleteRequestValidator") + public Function clearingMemberCategoryDeleteRequestValidator( + Map> imdgForValidation + ) { + return clearingMemberCategoryDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(clearingMemberCategoryDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_ClearingMemberCategory, + ClearingMemberCategory.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CategoryNotFound) + ); + }; + } + +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/CompanyValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java similarity index 93% rename from clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/CompanyValidationConfig.java rename to clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java index 09e6dc2a7..5c80d1569 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/CompanyValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java @@ -1,11 +1,9 @@ -package ru.spcex.clearing.company.config; +package ru.spcex.clearing.company.config.validation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; -//import ru.spcex.clearing.validation.common.FieldRequiredRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; 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 e39ce71e4..aeb939d09 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 @@ -1,30 +1,30 @@ -//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.generated.ClearingMemberCategory; -//import ru.spcex.clearing.imdg.IMDGDistributedNames; -//import ru.spcex.platform.classes.base.SpcexObjectBase; -//import ru.spcex.platform.imdg.api.Imdg; -//import ru.spcex.platform.imdg.api.ImdgProvider; -// -//import java.util.HashMap; -//import java.util.Map; -//import java.util.function.BiConsumer; -// -//@Configuration -//public class ValidationConfig { -// -// @Bean("imdgForValidation") -// public Map> imdgForValidation(ImdgProvider imdgProvider) { -// final Map> imdg = new HashMap<>(); -// BiConsumer> addImdg = (s, aClass) -> imdg.put(s, imdgProvider.getImdg(s, aClass)); -// -// addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); -// addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); -// -// return imdg; -// } -// -//} +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.generated.ClearingMemberCategory; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + +@Configuration +public class ValidationConfig { + + @Bean("imdgForValidation") + public Map> imdgForValidation(ImdgProvider imdgProvider) { + final Map> imdg = new HashMap<>(); + BiConsumer> addImdg = (s, aClass) -> imdg.put(s, imdgProvider.getImdg(s, aClass)); + + addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); + addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + + return imdg; + } + +} 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 6ca00b196..9692e5aff 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 @@ -6,6 +6,7 @@ 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.generated.ClearingMemberCategory; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -16,9 +17,13 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCat import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; 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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.validation.IValidator; + +import java.util.function.Function; @Service public class ClearingMemberCategoryService extends QueueConsumer implements InitializingBean { @@ -27,28 +32,24 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private final IMessageResolver messageResolver; - /* private final Function clearingMemberCategoryNewRequestValidator; private final Function clearingMemberCategoryUpdateRequestValidator; private final Function clearingMemberCategoryDeleteRequestValidator; - */ @Autowired public ClearingMemberCategoryService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, - IMessageResolver messageResolver /*, + IMessageResolver messageResolver, @Qualifier("clearingMemberCategoryNewRequestValidator") Function clearingMemberCategoryNewRequestValidator, @Qualifier("clearingMemberCategoryUpdateRequestValidator") Function clearingMemberCategoryUpdateRequestValidator, - @Qualifier("clearingMemberCategoryDeleteRequestValidator") Function clearingMemberCategoryDeleteRequestValidator */) { + @Qualifier("clearingMemberCategoryDeleteRequestValidator") Function clearingMemberCategoryDeleteRequestValidator) { super(kafkaQueue, kafkaProducer); this.clearingMemberCategoryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); this.messageResolver = messageResolver; - /* this.clearingMemberCategoryNewRequestValidator = clearingMemberCategoryNewRequestValidator; this.clearingMemberCategoryUpdateRequestValidator = clearingMemberCategoryUpdateRequestValidator; this.clearingMemberCategoryDeleteRequestValidator = clearingMemberCategoryDeleteRequestValidator; - */ } @Override @@ -68,8 +69,8 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); -// RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryNewRequestValidator, messageResolver); -// if (requestInfoUpdate != null) return requestInfoUpdate; + RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryNewRequestValidator, messageResolver); + if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("ClearingMemberCategoryUpdateRequest received {}", userRequest.getId()); ClearingMemberCategory newCategory = new ClearingMemberCategory(); @@ -85,8 +86,8 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init public RequestInfoUpdate clearingMemberCategoryUpdate(BaseRequest userRequest) { ClearingMemberCategoryUpdateRequest req = userRequest.getRequestPayload(); -// RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryUpdateRequestValidator, messageResolver); -// if (requestInfoUpdate != null) return requestInfoUpdate; + RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryUpdateRequestValidator, messageResolver); + if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("ClearingMemberCategoryUpdateRequest received"); ClearingMemberCategory clearingMemberCategory = clearingMemberCategoryMap.getSingleObjectByID(req.getId()); @@ -101,8 +102,8 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private RequestInfoUpdate clearingMemberCategoryDelete(BaseRequest userRequest) { CommonDeleteRequest req = userRequest.getRequestPayload(); -// RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryDeleteRequestValidator, messageResolver); -// if (requestInfoUpdate != null) return requestInfoUpdate; + RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryDeleteRequestValidator, messageResolver); + if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("CommonDeleteRequest received id = {}", req.getId()); ClearingMemberCategory clearingMemberCategory = clearingMemberCategoryMap.getSingleObjectByID(req.getId()); From 9e4b4fd7df3a320ce6c829df1e08a0e2c5f4a2f6 Mon Sep 17 00:00:00 2001 From: akulikov Date: Mon, 3 Apr 2023 12:15:33 +0300 Subject: [PATCH 09/90] fix pom.xml for clearing-utils --- clearing-parent/clearing-utils/pom.xml | 57 ------------------- .../utils/validation/IValidationRule.java | 1 - 2 files changed, 58 deletions(-) diff --git a/clearing-parent/clearing-utils/pom.xml b/clearing-parent/clearing-utils/pom.xml index 59e076a6b..4b9ecb09b 100644 --- a/clearing-parent/clearing-utils/pom.xml +++ b/clearing-parent/clearing-utils/pom.xml @@ -91,61 +91,4 @@ platform-messaging - - - - src/main/resources - - application.properties - - false - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - ru.spcex.clearing.imdg.IMDGApplication - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - true - ${project.artifactId} - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.21.0 - - - org.junit.platform - junit-platform-surefire-provider - 1.2.0-M1 - - - org.junit.jupiter - junit-jupiter-engine - 5.2.0-M1 - - - - - \ No newline at end of file diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java index 707751089..3ad88a3f1 100644 --- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java @@ -10,7 +10,6 @@ import java.util.Optional; * Все необходимые данные берет из контекста * @param контекст */ -// todo move this to clearing-utils (or move clearing-utils public interface IValidationRule { Optional validate(C context); From 0b062fc97c791590c7a65b1269d0a761129a98ad Mon Sep 17 00:00:00 2001 From: psemenkov Date: Mon, 3 Apr 2023 13:21:27 +0300 Subject: [PATCH 10/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20MoneyMark?= =?UTF-8?q?etSecurityService=20=D0=B8=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8E=20=D0=B2=20=D1=81=D0=BE=D0=BE=D1=82?= =?UTF-8?q?=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=81=20?= =?UTF-8?q?=D0=A2=D0=97.=20=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20MoneyMarketSecurityMapStore.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EquitySecurityMapStore.java | 8 +- .../object/MoneyMarketSecurityMapStore.java | 2 +- .../securities/component/ListingBuilder.java | 14 ++ .../securities/errors/SecuritiesError.java | 1 + .../service/cud/EquitySecurityService.java | 131 +++++++++++++++++ .../cud/MoneyMarketSecurityService.java | 20 ++- .../validation/ValidationProvider.java | 58 +++++++- .../validation/rule/EndDtAfterStartDt.java | 7 + .../rule/EquityNewValidationRule.java | 31 ++++ .../rule/IsValidInstrumentType.java | 32 +++++ .../validation/rule/MmsNewValidationRule.java | 31 ++-- .../rule/MmsUpdateValidationRule.java | 2 +- ...BySecuritySymbolAndWorkflowStatusActv.java | 44 ++++++ .../validation/rule/WorkflowStatusActv.java | 27 ++++ .../base/interfaces/WithInstrumentType.java | 5 + .../base/interfaces/WithWorkflowStatus.java | 5 + .../securitites/EquitySecurityNewRequest.java | 120 ++++++++++++++++ .../EquitySecurityUpdateRequest.java | 132 ++++++++++++++++++ .../MoneyMarketSecurityNewRequest.java | 84 ++++++++++- .../MoneyMarketSecurityUpdateRequest.java | 97 ++++++++++++- 20 files changed, 820 insertions(+), 31 deletions(-) create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentType.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/NotPresentBySecuritySymbolAndWorkflowStatusActv.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/WorkflowStatusActv.java create mode 100644 platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithInstrumentType.java create mode 100644 platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithWorkflowStatus.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java index 5efde75e6..24cb7ac06 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java @@ -7,9 +7,12 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.base.TemplateMapStore; import ru.spcex.platform.utils.time.TimeUtil; +import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; @Component public class EquitySecurityMapStore extends TemplateMapStore { @@ -31,7 +34,7 @@ public class EquitySecurityMapStore extends TemplateMapStore { @Override public String[] getFields() { return new String[]{ - "ID", "SECURITY_ID", "SHARE_TYPE" + "ID", "SECURITY_ID", "SHARE_TYPE", "LOT_SIZE" }; } @@ -55,6 +58,7 @@ public class EquitySecurityMapStore extends TemplateMapStore { object.setId(resultSet.getObject("ID", Long.class)); object.setSecurityId(resultSet.getObject("SECURITY_ID", Long.class)); object.setShareType(resultSet.getObject("SHARE_TYPE", String.class)); + object.setLotSize(resultSet.getObject("LOT_SIZE", BigDecimal.class)); fillBySecurity(object, object.getSecurityId()); return object; } diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/MoneyMarketSecurityMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/MoneyMarketSecurityMapStore.java index 0d4fbadf7..48a96b428 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/MoneyMarketSecurityMapStore.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/MoneyMarketSecurityMapStore.java @@ -72,7 +72,7 @@ public class MoneyMarketSecurityMapStore extends TemplateMapStore equitySecurityImdg; + private final Imdg

listingImdg; + private final ImdgProvider imdgProvider; + private final ImdgId idGenerator; + private final ValidationProvider validation; + private final IMessageResolver messageResolver; + private final ListingBuilder listingBuilder = new ListingBuilder(); + + @Autowired + public EquitySecurityService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationProvider validation, + IMessageResolver messageResolver) { + super(kafkaQueue, kafkaProducer); + this.validation = validation; + this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); + this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.messageResolver = messageResolver; + } + + @Override + public void afterPropertiesSet() { + callback(EquitySecurityNewRequest.class) + .setFunction(this::newEquity) + .forDestination(Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW, callbacks::put); + callback(EquitySecurityUpdateRequest.class) + .setFunction(this::updateEquity) + .forDestination(Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::deleteEquity) + .forDestination(Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE, callbacks::put); + imdgProvider.waitAvailable(); + init(); + } + + private RequestInfoUpdate newEquity(BaseRequest userRequest){ + ImdgTransaction transaction = imdgProvider.newTransaction(); + EquitySecurityNewRequest req = userRequest.getRequestPayload(); + Optional validationError = validation.equityNewValidator() + .apply(req) + .tillFirstError(); + if (validationError.isPresent()) { + String errorMsg = messageResolver.resolve(validationError.get()); + log.error("cannot process EquitySecurityNewRequest id={}: {}", userRequest.getId(), errorMsg); + return new RequestInfoUpdate() + .setId(userRequest.getId()) + .setStatus(Status.Error) + .setMessage(errorMsg); + } + log.debug("EquitySecurityNewRequest received"); + EquitySecurity equity = new EquitySecurity(); + equity.setId(idGenerator.nextId()); + equity.setSecuritySymbol(req.getSecuritySymbol()); + equity.setShortName(req.getShortName()); + equity.setFullName(req.getFullName()); + equity.setIsin(req.getIsin()); + equity.setShareType(req.getShareType()); + equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setIssuerId(req.getIssuerId()); + equity.setFullNameEng(req.getFullNameEng()); + equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + equity.setInstrumentType(req.getInstrumentType()); + equity.setSecurityId(equity.getId()); + equity.setCreated(Instant.now()); + try { + transaction.beginTransaction(); + Imdg equityImdg = transaction.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); + Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + //одним скопом выполняем реквест + equityImdg.insert(equity); + Listing listing = listingBuilder.byNewEquity(equity, req); + listingMap.insert(listing); + //и сохраняем обновленный +// reqInfoMap.insert(reqInfo); + transaction.commitTransaction(); + } catch (Throwable e) { + transaction.rollbackTransaction(); +// RequestInfo.update(reqInfo, Status.Error, ExceptionUtils.getStackTrace(e)); +// requestInfoImdg.insert(reqInfo); + } + log.debug("successfully processed, request id {}, new object id {}", userRequest.getId(), equity.getId()); + return null; // default success + } + + private RequestInfoUpdate updateEquity(BaseRequest userRequest){ + return null; + } + + private RequestInfoUpdate deleteEquity(BaseRequest userRequest) { + return null; + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java index ccf129c68..51190d495 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java @@ -111,11 +111,18 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setStartDate(req.getStartDate()); mms.setEndDate(req.getEndDate()); mms.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); + mms.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); mms.setNominalCurrency(req.getNominalCurrency()); mms.setInstrumentType(req.getInstrumentType()); mms.setFullName(req.getFullName()); + mms.setShortName(req.getShortName()); + mms.setFullNameEng(req.getFullNameEng()); + mms.setShortNameEng(req.getShortNameEng()); mms.setSecuritySymbol(req.getSecuritySymbol()); + mms.setTermType(req.getTermType()); + mms.setIsin(req.getIsin()); mms.setSecurityId(mms.getId()); + mms.setDescription(mms.getDescription()); mms.setCreated(Instant.now()); mms.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); try { @@ -157,16 +164,27 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setStartDate(req.getStartDate()); mms.setEndDate(req.getEndDate()); mms.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); + mms.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); mms.setNominalCurrency(req.getNominalCurrency()); mms.setInstrumentType(req.getInstrumentType()); mms.setFullName(req.getFullName()); + mms.setShortName(req.getShortName()); + mms.setFullNameEng(req.getFullNameEng()); + mms.setShortNameEng(req.getShortNameEng()); + mms.setSecuritySymbol(req.getSecuritySymbol()); + mms.setTermType(req.getTermType()); + mms.setIsin(req.getIsin()); + mms.setSecurityId(mms.getId()); + mms.setDescription(mms.getDescription()); + mms.setCreated(Instant.now()); + moneyMarketSecurityMap.update(mms); Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); if (listing == null) { log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId()); return null; } - listing.setLotSize(BigDecimal.valueOf(req.getLotSize())); + listing.setLotSize(mms.getLotSize()); listing.setUpdated(updateTime); listingImdg.update(listing); return null; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index 481aec643..8f09e27c5 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -3,13 +3,12 @@ package ru.spcex.clearing.securities.validation; import org.springframework.stereotype.Component; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; import ru.spcex.clearing.securities.errors.SecuritiesError; -import ru.spcex.clearing.securities.validation.rule.EndDtAfterStartDt; -import ru.spcex.clearing.securities.validation.rule.MmsDeleteValidationRule; -import ru.spcex.clearing.securities.validation.rule.MmsNewValidationRule; -import ru.spcex.clearing.securities.validation.rule.MmsUpdateValidationRule; +import ru.spcex.clearing.securities.validation.rule.*; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -23,10 +22,12 @@ import java.util.function.Function; @Component public class ValidationProvider { private final Imdg mmsMap; + private final Imdg equityMap; public ValidationProvider(ImdgProvider imdgProvider) { this.mmsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, SpcexObjectBase.class); + this.equityMap = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, SpcexObjectBase.class); } public Function mmsNewValidator() { @@ -36,7 +37,9 @@ public class ValidationProvider { context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); return new ValidatorImpl<>(context, EndDtAfterStartDt.instance(MoneyMarketSecurityNewRequest.class), - MmsNewValidationRule.SecuritySymbolUniq + new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentAlreadyExists, MoneyMarketSecurityNewRequest.class), + new IsValidInstrumentType(SecuritiesError.RequiredFieldIsEmpty, "RATE"), + MmsNewValidationRule.RequiredFieldIsNotEmpty ); }; } @@ -48,8 +51,9 @@ public class ValidationProvider { context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); return new ValidatorImpl<>(context, EndDtAfterStartDt.instance(MoneyMarketSecurityUpdateRequest.class), + new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "RATE"), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), - MmsUpdateValidationRule.StatusIsActive + new WorkflowStatusActv() ); }; } @@ -60,8 +64,48 @@ public class ValidationProvider { context.setValidatedObject(mmsRequest); context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); return new ValidatorImpl<>(context, + new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "RATE"), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), - MmsDeleteValidationRule.StatusIsActive + new WorkflowStatusActv() + ); + }; + } + + public Function equityNewValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); + return new ValidatorImpl<>(context, + new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentAlreadyExists, EquitySecurityNewRequest.class), + new IsValidInstrumentType(SecuritiesError.RequiredFieldIsEmpty, "EQTY"), + EquityNewValidationRule.RequiredFieldIsNotEmpty + ); + }; + } + + public Function equityUpdateValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); + return new ValidatorImpl<>(context, + new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "EQTY"), + new PresentById(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentNotFound, true), + new WorkflowStatusActv() + ); + }; + } + + public Function equityDeleteValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); + return new ValidatorImpl<>(context, + new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "EQTY"), + new PresentById(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentNotFound, true), + new WorkflowStatusActv() ); }; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EndDtAfterStartDt.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EndDtAfterStartDt.java index c565f5f83..7bb343892 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EndDtAfterStartDt.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EndDtAfterStartDt.java @@ -20,6 +20,13 @@ public class EndDtAfterStartDt implements IVa @Override public Optional validate(ImdgValidationContext context) { T validatedObject = context.getValidatedObject(); + if(validatedObject.getEndDate() == null && validatedObject.getStartDate() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "endDate", "startDate"); + } + if(validatedObject.getEndDate() == null || validatedObject.getStartDate() == null){ + if(validatedObject.getStartDate() == null) return of(SecuritiesError.RequiredFieldIsEmpty, "startDate"); + return of(SecuritiesError.RequiredFieldIsEmpty, "endDate"); + } if (validatedObject.getEndDate().isBefore(validatedObject.getStartDate())) { return of(SecuritiesError.WrongFieldValue, "endDate"); } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java new file mode 100644 index 000000000..31d2cb36a --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java @@ -0,0 +1,31 @@ +package ru.spcex.clearing.securities.validation.rule; + +import org.springframework.util.StringUtils; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; +import ru.spcex.clearing.securities.errors.SecuritiesError; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; + +public enum EquityNewValidationRule implements IValidationRule> { + RequiredFieldIsNotEmpty() { + @Override + public Optional validate(ImdgValidationContext context) { + EquitySecurityNewRequest action = context.getValidatedObject(); + if (StringUtils.hasText(action.getShortName())){ + return of(SecuritiesError.RequiredFieldIsEmpty, "shortName"); + } + if (action.getLotSize() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "lotSize"); + } + return empty(); + } + }; + + @Override + public String ruleName() { + return "MmsNewValidationRule." + name(); + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentType.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentType.java new file mode 100644 index 000000000..04c8878d7 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentType.java @@ -0,0 +1,32 @@ +package ru.spcex.clearing.securities.validation.rule; + +import ru.spcex.clearing.securities.errors.SecuritiesError; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; + +public class IsValidInstrumentType implements IValidationRule> { + private final IEnumId errorEnum; + private final String predictableInstrumentType; + + public IsValidInstrumentType(IEnumId errorEnum, String predictableInstrumentType) { + this.errorEnum = errorEnum; + this.predictableInstrumentType = predictableInstrumentType; + } + + @Override + public Optional validate(ImdgValidationContext context) { + WithInstrumentType action = context.getValidatedObject(); + if (action.getInstrumentType() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty); + } else if (!predictableInstrumentType.equalsIgnoreCase(action.getInstrumentType())){ + return of(errorEnum); + }else { + return empty(); + } + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java index 550491385..de4eaff95 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java @@ -1,32 +1,35 @@ package ru.spcex.clearing.securities.validation.rule; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; -import ru.spcex.clearing.imdg.IMDGDistributedNames; +import org.springframework.util.StringUtils; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; import ru.spcex.clearing.securities.errors.SecuritiesError; -import ru.spcex.platform.enumeration.Status; -import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.validation.IValidationRule; -import java.util.Map; import java.util.Optional; public enum MmsNewValidationRule implements IValidationRule> { - SecuritySymbolUniq() { + RequiredFieldIsNotEmpty() { @Override public Optional validate(ImdgValidationContext context) { MoneyMarketSecurityNewRequest action = context.getValidatedObject(); - Imdg mmsImdg = context.obtainMap(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class); - MoneyMarketSecurity mms = mmsImdg.getSingleObjectByFieldValues(Map.of( - "securitySymbol", action.getSecuritySymbol(), - "workflowStatus", Status.Active.getKey())); - if (mms != null) { - return of(SecuritiesError.InstrumentAlreadyExists); - } else { - return empty(); + if (StringUtils.hasText(action.getShortName())){ + return of(SecuritiesError.RequiredFieldIsEmpty, "shortName"); } + if (action.getLotSize() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "lotSize"); + } + if (action.getNominalValue() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "nominalValue"); + } + if (StringUtils.hasText(action.getNominalCurrency())) { + return of(SecuritiesError.RequiredFieldIsEmpty, "nominalCurrency"); + } + if (StringUtils.hasText(action.getTermType())) { + return of(SecuritiesError.RequiredFieldIsEmpty, "termType"); + } + return empty(); } }; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java index 1d88b45bb..c2b681924 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsUpdateValidationRule.java @@ -18,7 +18,7 @@ public enum MmsUpdateValidationRule implements IValidationRule implements IValidationRule> { + private final String mapName; + private final IEnumId errorEnum; + private final Class clazz; + + public NotPresentBySecuritySymbolAndWorkflowStatusActv(String mapName, IEnumId errorEnum, Class clazz) { + this.mapName = mapName; + this.errorEnum = errorEnum; + this.clazz = clazz; + } + + @Override + public Optional validate(ImdgValidationContext context) { + WithSecuritySymbol action = context.getValidatedObject(); + Imdg imdg = context.obtainMap(mapName, clazz); + if(StringUtils.hasText(action.getSecuritySymbol())) { + return of(SecuritiesError.RequiredFieldIsEmpty, "securitySymbole"); + } + T object = imdg.getSingleObjectByFieldValues(Map.of( + "securitySymbol", action.getSecuritySymbol(), + "workflowStatus", Status.Active.getKey())); + if (object != null) { + return of(errorEnum); + } else { + return empty(); + } + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/WorkflowStatusActv.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/WorkflowStatusActv.java new file mode 100644 index 000000000..e374c914d --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/WorkflowStatusActv.java @@ -0,0 +1,27 @@ +package ru.spcex.clearing.securities.validation.rule; + +import ru.spcex.clearing.securities.errors.SecuritiesError; +import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; +import ru.spcex.platform.enumeration.Status; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.imdg.validation.Stored; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; + +public class WorkflowStatusActv implements IValidationRule> { + + @Override + public Optional validate(ImdgValidationContext context) { + WithWorkflowStatus object = context.getStoredObject(Stored.PresentById); + //проверка только если PresentById найдет объект и сохранит его + if (object != null && object.getWorkflowStatus() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "workflowStatus"); + }else if (object != null && !Status.Active.getKey().equals(object.getWorkflowStatus())) { + return of(SecuritiesError.InstrumentNotActive, object.getClass().getSimpleName()); + } else { + return empty(); + } + } +} diff --git a/platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithInstrumentType.java b/platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithInstrumentType.java new file mode 100644 index 000000000..20a18740b --- /dev/null +++ b/platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithInstrumentType.java @@ -0,0 +1,5 @@ +package ru.spcex.platform.classes.base.interfaces; + +public interface WithInstrumentType { + String getInstrumentType(); +} diff --git a/platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithWorkflowStatus.java b/platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithWorkflowStatus.java new file mode 100644 index 000000000..35de84fc8 --- /dev/null +++ b/platform-parent/platform-classes-base/src/main/java/ru/spcex/platform/classes/base/interfaces/WithWorkflowStatus.java @@ -0,0 +1,5 @@ +package ru.spcex.platform.classes.base.interfaces; + +public interface WithWorkflowStatus { + String getWorkflowStatus(); +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java new file mode 100644 index 000000000..909618598 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java @@ -0,0 +1,120 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; +import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; + +public class EquitySecurityNewRequest implements WithSecuritySymbol, WithInstrumentType { + @JsonProperty + public String securitySymbol; + @JsonProperty + public String shortName; + @JsonProperty + public String fullName; + @JsonProperty + public String isin; + @JsonProperty + public String shareType; + @JsonProperty + public Double lotSize; + @JsonProperty + public Long issuerId; + @JsonProperty + public String shortNameEng; + @JsonProperty + public String fullNameEng; + @JsonProperty + public String workflowStatus; + @JsonProperty + public String instrumentType; + + @Override + public String getSecuritySymbol() { + return securitySymbol; + } + + public void setSecuritySymbol(String securitySymbol) { + this.securitySymbol = securitySymbol; + } + + 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 getIsin() { + return isin; + } + + public void setIsin(String isin) { + this.isin = isin; + } + + public String getShareType() { + return shareType; + } + + public void setShareType(String shareType) { + this.shareType = shareType; + } + + public Double getLotSize() { + return lotSize; + } + + public void setLotSize(Double lotSize) { + this.lotSize = lotSize; + } + + public Long getIssuerId() { + return issuerId; + } + + public void setIssuerId(Long issuerId) { + this.issuerId = issuerId; + } + + 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 getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } + + @Override + public String getInstrumentType() { + return instrumentType; + } + + public void setInstrumentType(String instrumentType) { + this.instrumentType = instrumentType; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java new file mode 100644 index 000000000..fb4806e79 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java @@ -0,0 +1,132 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import ru.spcex.platform.classes.base.interfaces.WithId; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; +import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; + +public class EquitySecurityUpdateRequest implements WithId, WithInstrumentType, WithWorkflowStatus { + @JsonProperty + public Long id; + @JsonProperty + public String securitySymbol; + @JsonProperty + public String shortName; + @JsonProperty + public String fullName; + @JsonProperty + public String isin; + @JsonProperty + public String shareType; + @JsonProperty + public Double lotSize; + @JsonProperty + public Long issuerId; + @JsonProperty + public String shortNameEng; + @JsonProperty + public String fullNameEng; + @JsonProperty + public String workflowStatus; + @JsonProperty + public String instrumentType; + + @Override + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getSecuritySymbol() { + return securitySymbol; + } + + public void setSecuritySymbol(String securitySymbol) { + this.securitySymbol = securitySymbol; + } + + 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 getIsin() { + return isin; + } + + public void setIsin(String isin) { + this.isin = isin; + } + + public String getShareType() { + return shareType; + } + + public void setShareType(String shareType) { + this.shareType = shareType; + } + + public Double getLotSize() { + return lotSize; + } + + public void setLotSize(Double lotSize) { + this.lotSize = lotSize; + } + + public Long getIssuerId() { + return issuerId; + } + + public void setIssuerId(Long issuerId) { + this.issuerId = issuerId; + } + + 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; + } + + @Override + public String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } + + @Override + public String getInstrumentType() { + return instrumentType; + } + + public void setInstrumentType(String instrumentType) { + this.instrumentType = instrumentType; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java index 0527de865..44466ac0f 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java @@ -6,11 +6,13 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; import ru.spcex.platform.classes.base.interfaces.WithEndDt; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; +import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; import ru.spcex.platform.classes.base.interfaces.WithStartDt; import java.time.LocalDate; -public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt { +public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt, WithSecuritySymbol, WithInstrumentType { @JsonProperty @JsonSerialize(using = LocalDateSerializer.class) @JsonDeserialize(using = LocalDateDeserializer.class) @@ -26,11 +28,27 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt { @JsonProperty public String instrumentType; @JsonProperty + public String shortName; + @JsonProperty public String fullName; @JsonProperty + public String shortNameEng; + @JsonProperty + public String fullNameEng; + @JsonProperty public String securitySymbol; @JsonProperty public Double lotSize; + @JsonProperty + public String termType; + @JsonProperty + public String description; + @JsonProperty + public Long issuerId; + @JsonProperty + public String isin; + @JsonProperty + public String workflowStatus; public LocalDate getStartDate() { return startDate; @@ -80,6 +98,14 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt { this.fullName = fullName; } + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + public String getSecuritySymbol() { return securitySymbol; } @@ -95,4 +121,60 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt { public void setLotSize(Double lotSize) { this.lotSize = lotSize; } + + public String getTermType() { + return termType; + } + + public void setTermType(String termType) { + this.termType = termType; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Long getIssuerId() { + return issuerId; + } + + public void setIssuerId(Long issuerId) { + this.issuerId = issuerId; + } + + 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 getIsin() { + return isin; + } + + public void setIsin(String isin) { + this.isin = isin; + } + + public String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java index 15b584b24..9778597b7 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java @@ -6,13 +6,11 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; -import ru.spcex.platform.classes.base.interfaces.WithEndDt; -import ru.spcex.platform.classes.base.interfaces.WithId; -import ru.spcex.platform.classes.base.interfaces.WithStartDt; +import ru.spcex.platform.classes.base.interfaces.*; import java.time.LocalDate; -public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, WithEndDt { +public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, WithEndDt, WithInstrumentType, WithWorkflowStatus { @JsonProperty public Long id; @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Europe/Moscow") @@ -32,9 +30,27 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi @JsonProperty public String instrumentType; @JsonProperty + public String shortName; + @JsonProperty public String fullName; @JsonProperty + public String shortNameEng; + @JsonProperty + public String fullNameEng; + @JsonProperty + public String securitySymbol; + @JsonProperty public Double lotSize; + @JsonProperty + public String termType; + @JsonProperty + public String description; + @JsonProperty + public Long issuerId; + @JsonProperty + public String isin; + @JsonProperty + public String workflowStatus; public Long getId() { return id; @@ -84,6 +100,79 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi this.fullName = fullName; } + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + + 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 getSecuritySymbol() { + return securitySymbol; + } + + public void setSecuritySymbol(String securitySymbol) { + this.securitySymbol = securitySymbol; + } + + public String getTermType() { + return termType; + } + + public void setTermType(String termType) { + this.termType = termType; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Long getIssuerId() { + return issuerId; + } + + public void setIssuerId(Long issuerId) { + this.issuerId = issuerId; + } + + public String getIsin() { + return isin; + } + + public void setIsin(String isin) { + this.isin = isin; + } + + public String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } + public Double getLotSize() { return lotSize; } From 5ed307f6396a169e9d0efb7f9dc9cf224d10aa6c Mon Sep 17 00:00:00 2001 From: AKurakin Date: Mon, 3 Apr 2023 14:19:09 +0300 Subject: [PATCH 11/90] http://jira.mfd.msk:8088/browse/CLS-259 . --- .../company/service/CompanyService.java | 47 +++++++++++-- .../clearing/company/util/RequestHelper.java | 70 +++++++++++++++++++ 2 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java 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 007058195..2995c5361 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 @@ -9,20 +9,26 @@ 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.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.CompanyNewRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; -//import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.platform.enumeration.*; 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.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.log.ExceptionUtils; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; @@ -57,11 +63,12 @@ public class CompanyService extends QueueConsumer implements InitializingBean { @Override public void afterPropertiesSet() { + RequestHelper requestHelper = new RequestHelper(log, messageResolver); callback(CommonDeleteRequest.class) .setConsumer(this::deleteCompany) .forDestination(Consts.DESTINATION_COMPANY_DELETE, callbacks::put); callback(CompanyNewRequest.class) - .setConsumer(this::createCompany) + .setFunction( request -> requestHelper.requestFunction(this::createCompany, request)) .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); callback(CompanyNewRequest.class) .setConsumer(this::updateCompany) @@ -72,6 +79,31 @@ public class CompanyService extends QueueConsumer implements InitializingBean { // .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); init(); } +// +// interface RequestCommand { +// Long command(T arg) throws ClearingBaseException; +// } +// +// protected > Object requestFunction(RequestCommand command, T userRequest) { +// try { +// Long itemAffected = command.command(userRequest); +// log.trace("Item affected: {}", itemAffected); +// return null; +// } catch (ClearingBaseException expectedE) { +// log.trace("{} return expected exception: {}", command, expectedE.toString()); +// return new RequestInfoUpdate() +// .setId(userRequest.getId()) +// .setStatus(Status.Error) +// .setMessage(expectedE.getMessage()); +// } catch (Exception unexpectedE) { +// log.error("Error at {}: {} ", command, ExceptionUtils.getStackTrace(unexpectedE)); +// String message = messageResolver.resolve(new EnumMessage(CompanyErrors.GeneralError)); +// return new RequestInfoUpdate() +// .setId(userRequest.getId()) +// .setStatus(Status.Error) +// .setMessage(message); +// } +// } protected void validateRole(BaseRequest req) throws ValidationException { Long requestor = null; // todo требуется передавать это значение из frontendapi! req.getUserId(); @@ -85,7 +117,8 @@ public class CompanyService extends QueueConsumer implements InitializingBean { Optional error = validator.tillFirstError(); if (error.isPresent()) { log.warn("CompanyNewRequest validation error: {}", error.get()); - String errorMsg = messageResolver.resolve(error.get()); + throw new ValidationException(error.get()); +// String errorMsg = messageResolver.resolve(error.get()); // return new RequestInfoUpdate() // todo reply message // .setId(userRequest.getId()) // .setStatus(Status.Error) @@ -93,14 +126,12 @@ public class CompanyService extends QueueConsumer implements InitializingBean { } } - private void createCompany(BaseRequest companyNewRequestBaseRequest) { + private Long createCompany(BaseRequest companyNewRequestBaseRequest) throws ValidationException { CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); - try { + { // Валидация, ValidationException validateRole(companyNewRequestBaseRequest); validate(req); - } catch (ValidationException e) { - throw new RuntimeException(e); // todo true return error } Company company = new Company(); company.setId(idSequence.nextId()); @@ -124,6 +155,8 @@ public class CompanyService extends QueueConsumer implements InitializingBean { companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); + + return company.getId(); } 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 new file mode 100644 index 000000000..5cbb5d6da --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java @@ -0,0 +1,70 @@ +package ru.spcex.clearing.company.util; + +import org.slf4j.Logger; +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; +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 java.util.Objects; + +/** + * Упрощает обработку ошибок во время обработки реквестов. + * Передаёт регламинтированные ошибки из ClearingBaseException. + * + * Пример: + * callback(CompanyNewRequest.class) + * .setFunction( request -> requestHelper.requestFunction(this::createCompany, request)) + * .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); + */ +public class RequestHelper { + protected final Logger log; + protected final IMessageResolver messageResolver; + + public RequestHelper(Logger log, IMessageResolver messageResolver) { + Objects.requireNonNull(log); + Objects.requireNonNull(messageResolver); + this.log = log; + this.messageResolver = messageResolver; + } + + /** + * Оборачивает функцию command в try-catch + * @param command обработчик реквеста + * @param userRequest реквест + * @param request payload type + * @param тип BaseRequest + * @return RequestInfoUpdate или null + */ + public > RequestInfoUpdate requestFunction(RequestCommand command, T userRequest) { + try { + Long itemAffected = command.command(userRequest); + log.trace("Item affected: {}", itemAffected); + return null; + } catch (ClearingBaseException expectedE) { + log.trace("{} return expected exception: {}", command, expectedE.toString()); + String message = expectedE.getEnumMsg() == null + ? expectedE.getMessage() + : messageResolver.resolve(expectedE.getEnumMsg()); + 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)); + return new RequestInfoUpdate() + .setId(userRequest.getId()) + .setStatus(Status.Error) + .setMessage(message); + } + } + + public interface RequestCommand { + Long command(T arg) throws ClearingBaseException; + } +} From 50e5d8d7bceda134363638a2f843f35f93c585e0 Mon Sep 17 00:00:00 2001 From: akulikov Date: Mon, 3 Apr 2023 15:13:49 +0300 Subject: [PATCH 12/90] fix ValidationHelper: method validate (now validateTillFirstError) static -> not static --- .../validation/common/ValidationHelper.java | 25 ++++++++++++++++--- .../config/validation/ValidationConfig.java | 7 ++++++ .../ClearingMemberCategoryService.java | 14 +++++------ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java index 910ce7795..5c57061cf 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java @@ -15,9 +15,20 @@ import java.util.function.Function; public class ValidationHelper { private final static Logger log = LoggerFactory.getLogger(ValidationHelper.class); - public static RequestInfoUpdate validate(BaseRequest userRequest, - Function validatorBuilder, - IMessageResolver messageResolver) { + private IMessageResolver messageResolver; + + public ValidationHelper(IMessageResolver messageResolver) { + this.messageResolver = messageResolver; + } + + /** + * Валидация запроса до первой ошибки + * + * @param Класс проверяемого запроса + * @return null если ошибок нет + */ + public RequestInfoUpdate validateTillFirstError(BaseRequest userRequest, + Function validatorBuilder) { if (validatorBuilder != null) { R req = userRequest.getRequestPayload(); IValidator validator = validatorBuilder.apply(req); @@ -34,4 +45,12 @@ public class ValidationHelper { return null; } + + public IMessageResolver getMessageResolver() { + return messageResolver; + } + + public void setMessageResolver(IMessageResolver messageResolver) { + this.messageResolver = messageResolver; + } } 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 aeb939d09..9098271e0 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 @@ -5,9 +5,11 @@ import org.springframework.context.annotation.Configuration; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.generated.ClearingMemberCategory; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.IMessageResolver; import java.util.HashMap; import java.util.Map; @@ -27,4 +29,9 @@ public class ValidationConfig { return imdg; } + @Bean("validationHelper") + public ValidationHelper validationHelper(IMessageResolver messageResolver) { + return new ValidationHelper(messageResolver); + } + } 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 9692e5aff..e3e928473 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 @@ -20,7 +20,6 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; 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.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; import java.util.function.Function; @@ -30,26 +29,25 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg clearingMemberCategoryMap; - private final IMessageResolver messageResolver; - private final Function clearingMemberCategoryNewRequestValidator; private final Function clearingMemberCategoryUpdateRequestValidator; private final Function clearingMemberCategoryDeleteRequestValidator; + private final ValidationHelper validationHelper; @Autowired public ClearingMemberCategoryService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, - IMessageResolver messageResolver, + ValidationHelper validationHelper, @Qualifier("clearingMemberCategoryNewRequestValidator") Function clearingMemberCategoryNewRequestValidator, @Qualifier("clearingMemberCategoryUpdateRequestValidator") Function clearingMemberCategoryUpdateRequestValidator, @Qualifier("clearingMemberCategoryDeleteRequestValidator") Function clearingMemberCategoryDeleteRequestValidator) { super(kafkaQueue, kafkaProducer); this.clearingMemberCategoryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); - this.messageResolver = messageResolver; this.clearingMemberCategoryNewRequestValidator = clearingMemberCategoryNewRequestValidator; this.clearingMemberCategoryUpdateRequestValidator = clearingMemberCategoryUpdateRequestValidator; this.clearingMemberCategoryDeleteRequestValidator = clearingMemberCategoryDeleteRequestValidator; + this.validationHelper = validationHelper; } @Override @@ -69,7 +67,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); - RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryNewRequestValidator, messageResolver); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryNewRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("ClearingMemberCategoryUpdateRequest received {}", userRequest.getId()); @@ -86,7 +84,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init public RequestInfoUpdate clearingMemberCategoryUpdate(BaseRequest userRequest) { ClearingMemberCategoryUpdateRequest req = userRequest.getRequestPayload(); - RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryUpdateRequestValidator, messageResolver); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryUpdateRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("ClearingMemberCategoryUpdateRequest received"); @@ -102,7 +100,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private RequestInfoUpdate clearingMemberCategoryDelete(BaseRequest userRequest) { CommonDeleteRequest req = userRequest.getRequestPayload(); - RequestInfoUpdate requestInfoUpdate = ValidationHelper.validate(userRequest, clearingMemberCategoryDeleteRequestValidator, messageResolver); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryDeleteRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("CommonDeleteRequest received id = {}", req.getId()); From ae1d52794a1e6a26386d8d2d825e3a8989c812c1 Mon Sep 17 00:00:00 2001 From: ialbert Date: Mon, 3 Apr 2023 15:53:05 +0300 Subject: [PATCH 13/90] http://jira.mfd.msk:8088/browse/CLS-254 meta webtype --- .../clearing/backendapi/meta/ActionField.java | 9 ++++++ .../backendapi/meta/GetResponseFactory.java | 19 +++++++++++-- .../src/main/resources/meta/meta.xml | 28 +++++++++---------- .../spcex/platform/utils/time/TimeUtil.java | 11 ++++++++ 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ActionField.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ActionField.java index b672c14cd..8ae5447b1 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ActionField.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ActionField.java @@ -52,6 +52,11 @@ public class ActionField { @JsonSerialize(using = MetaDataTypeSerializer.class, include = JsonSerialize.Inclusion.NON_EMPTY) private MetaDataTypes type; + @JsonProperty(value = "webtype") + @JsonDeserialize(using = MetaDataTypeDeserializer.class) + @JsonSerialize(using = MetaDataTypeSerializer.class, include = JsonSerialize.Inclusion.NON_EMPTY) + private MetaDataTypes webtype; + @JsonProperty(value = "virtual") @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY) private Boolean virtual; @@ -115,4 +120,8 @@ public class ActionField { public void setVirtual(Boolean virtual) { this.virtual = virtual; } + + public MetaDataTypes getWebtype() { + return webtype; + } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java index 01f10dff7..557ae545e 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java @@ -5,9 +5,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import ru.spcex.platform.utils.time.TimeUtil; import java.text.SimpleDateFormat; import java.time.Instant; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; @@ -82,7 +84,7 @@ public class GetResponseFactory { currentField = field; // if (fieldsToAdd.contains(field.getField().getCode())) { try { - add(r, field.getField().getCode(), field.extractValue(o)); + add(r, field, field.extractValue(o)); } catch (Throwable e) { log.trace(ExceptionUtils.getStackTrace( new RuntimeException(String.format("Can't extract value for field='%s' of %s(%s): %s -> %s\n%s", @@ -102,9 +104,20 @@ public class GetResponseFactory { return r; } - private void add(Map response, String name, Object value) { + private void add(Map response, FieldExtracted fieldExtracted, Object value) { + MetaDataTypes webtype = fieldExtracted.getField().getWebtype(); + String name = fieldExtracted.getField().getCode(); Object data; - if (value instanceof Date) { + if (webtype != null && !MetaDataTypes.Time.equals(webtype)) { + throw new IllegalStateException("not implemented transforming " + webtype); + } else if (value != null && MetaDataTypes.Time.equals(webtype)) { + if (value instanceof Instant) { + LocalDateTime dtTm = TimeUtil.toDateTime((Instant) value); + data = timeFormatter.format(dtTm.toLocalTime()); + } else { + throw new IllegalStateException("not implemented transforming "); + } + } else if (value instanceof Date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+03:00"); data = sdf.format(value); } else if (value instanceof Instant) { diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index 36e2c2a44..640e1b1ef 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -254,8 +254,8 @@ - - + + @@ -291,8 +291,8 @@ - - + + @@ -313,8 +313,8 @@ - - + + @@ -468,8 +468,8 @@ - - + + @@ -672,8 +672,8 @@ - - + + @@ -683,13 +683,13 @@
- - + + - - + + diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java index 49fcb22b6..d6efc9f5e 100644 --- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java @@ -68,4 +68,15 @@ public class TimeUtil { if (date == null) return null; return LocalDate.ofInstant(date, ZoneId.systemDefault()); } + + public static ZonedDateTime toZoned(Instant instant) { + if (instant == null) return null; + return instant.atZone(zone); + } + + public static LocalDateTime toDateTime(Instant instant) { + ZonedDateTime zoned = toZoned(instant); + if (zoned == null) return null; + return zoned.toLocalDateTime(); + } } From 2032c156a89becaf4e9658c12b582dc78033e9d6 Mon Sep 17 00:00:00 2001 From: akulikov Date: Mon, 3 Apr 2023 17:39:04 +0300 Subject: [PATCH 14/90] ClearingMemberCategoryServiceTest fix --- .../common/rules/DictionaryPresentRule.java | 1 - .../clearing/company/config/KafkaConfig.java | 4 +- ...learingMemberCategoryValidationConfig.java | 10 ++- .../config/validation/ValidationConfig.java | 2 + .../company/service/CompanyService.java | 8 +-- .../ClearingMemberCategoryServiceTest.java | 64 +++++++++++++++---- 6 files changed, 63 insertions(+), 26 deletions(-) diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java index 130e3ecef..67b6586c9 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -93,7 +93,6 @@ public record DictionaryPresentRule(String fiel if (fromMap.isEmpty()) { return of(errorWrongDictionaryValue, fieldName); } - assert fromMap.size() == 1; D dictionaryFromMap = fromMap.iterator().next(); if (dictionaryFromMap == null) { return of(errorWrongDictionaryValue, fieldName); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/KafkaConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/KafkaConfig.java index 0be729887..40334c15c 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/KafkaConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/KafkaConfig.java @@ -15,13 +15,13 @@ import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory; public class KafkaConfig { @Autowired @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - @Bean + @Bean("kafkaConsumer") public Consumer createConsumer(CompanyServiceSettings settings) { return KafkaConsumerFactory.consumer(settings.getKafkaConsumer()); } @Autowired - @Bean + @Bean("kafkaProducer") public Producer createProducer(CompanyServiceSettings settings) { return KafkaProducerFactory.producer(settings.getKafkaProducer()); } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java index c73dc84b8..c41e4283d 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java @@ -12,7 +12,6 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCat import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; 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.ClearingCategory; @@ -38,6 +37,7 @@ public class ClearingMemberCategoryValidationConfig { context.setValidatedObject(clearingMemberCategoryNewRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); return new ValidatorImpl<>(context, IdPresentRule.instance("companyId", ClearingMemberCategoryNewRequest::getCompanyId, @@ -46,9 +46,12 @@ public class ClearingMemberCategoryValidationConfig { CompanyErrors.RequiredFieldEmpty, CompanyErrors.CompanyNotFound, company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), - FieldRequiredRule.instance("clearingMemberCategory", + DictionaryPresentRule.instance("clearingMemberCategory", ClearingMemberCategoryNewRequest::getClearingMemberCategory, - CompanyErrors.RequiredFieldEmpty)); + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CategoryNotFound)); }; } @@ -61,6 +64,7 @@ public class ClearingMemberCategoryValidationConfig { context.setValidatedObject(clearingMemberCategoryUpdateRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); return new ValidatorImpl<>(context, IdPresentRule.instance("id", 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 9098271e0..617eceff3 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 @@ -4,6 +4,7 @@ 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.generated.ClearingMemberCategory; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -25,6 +26,7 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary, ClearingCategoryDictionary.class); return imdg; } 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 2995c5361..9a38c614d 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 @@ -9,7 +9,6 @@ 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.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; @@ -17,18 +16,13 @@ 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.platform.messaging.service.QueueConsumer; -import ru.spcex.clearing.util.security.UserRoleVerification; -import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; -import ru.spcex.clearing.platform.messaging.service.Status; -import ru.spcex.platform.enumeration.*; +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.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.log.ExceptionUtils; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java index 5c7b9680a..25ae9344b 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java @@ -13,9 +13,14 @@ 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.generated.ClearingMemberCategory; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.ClearingMemberCategoryValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory.Matcher; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; @@ -23,6 +28,8 @@ 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.ClearingMemberCategoryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; +import ru.spcex.platform.enumeration.ClearingCategory; +import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @@ -34,7 +41,10 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, ClearingMemberCategoryService.class, + ClearingMemberCategoryValidationConfig.class, KafkaConfigTest.class, HazelcastServiceTestConfiguration.class}) class ClearingMemberCategoryServiceTest { @@ -44,7 +54,7 @@ class ClearingMemberCategoryServiceTest { private static final String TOPIC_MEMBER_CATEGORY_NEW = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_NEW; private static final String TOPIC_MEMBER_CATEGORY_UPDATE = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_UPDATE; private static final String TOPIC_MEMBER_CATEGORY_DELETE = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_DELETE; - private static final Long ID = currentID.getAndIncrement(); + private static final Long ID = currentID.incrementAndGet(); @Autowired ClearingMemberCategoryService clearingMemberCategoryService; @Autowired @@ -57,22 +67,48 @@ class ClearingMemberCategoryServiceTest { @SpyBean private MockProducer mockProducer; + private final long COMPANY_ID = 777L; + private Company TEST_COMPANY; + + private final String CLEARING_CATEGORY_DICT_CODE = ClearingCategory.B.getKey(); + private ClearingCategoryDictionary clearingCategoryDictionary; + @PostConstruct private void init() { hazelcastServiceTest.waitAvailable(); - memberCategoryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + memberCategoryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ClearingMemberCategory, + ClearingMemberCategory.class + ); + Imdg clearingCategoryDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class + ); + + Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + TEST_COMPANY = new Company(); + TEST_COMPANY.setId(COMPANY_ID); + TEST_COMPANY.setWorkflowStatus(WorkflowStatus.Active.getKey()); + companyImdg.insert(TEST_COMPANY); + + clearingCategoryDictionary = new ClearingCategoryDictionary(); + clearingCategoryDictionary.setCode(CLEARING_CATEGORY_DICT_CODE); + clearingCategoryDictionaryImdg.insert(clearingCategoryDictionary); + } @Test void clearingMemberCategoryNew() throws InterruptedException { //ARRANGE - String clearingMemberCategory = "1234"; + String clearingMemberCategory = CLEARING_CATEGORY_DICT_CODE; ClearingMemberCategoryNewRequest memberCategoryNewRequest = new ClearingMemberCategoryNewRequest(); memberCategoryNewRequest.setClearingMemberCategory(clearingMemberCategory); + memberCategoryNewRequest.setCompanyId(TEST_COMPANY.getId()); ClearingMemberCategory predictableClearingMemberCategory = new ClearingMemberCategory(); predictableClearingMemberCategory.setId(ID); - predictableClearingMemberCategory.setClearingMemberCategory("1234"); + predictableClearingMemberCategory.setCompanyId(COMPANY_ID); + predictableClearingMemberCategory.setClearingMemberCategory(clearingMemberCategory); //ACT String jsonString = getJsonStringForNew(memberCategoryNewRequest, ID); @@ -95,17 +131,19 @@ class ClearingMemberCategoryServiceTest { @Test void clearingMemberCategoryUpdate() throws InterruptedException { //ARRANGE - String clearingMemberCategory = "1234"; - ClearingMemberCategory existsСlearingMemberCategory = new ClearingMemberCategory(); - existsСlearingMemberCategory.setId(ID); - existsСlearingMemberCategory.setClearingMemberCategory("0000"); - memberCategoryImdg.insert(existsСlearingMemberCategory); + String clearingMemberCategory = CLEARING_CATEGORY_DICT_CODE; + ClearingMemberCategory existsClearingMemberCategory = new ClearingMemberCategory(); + existsClearingMemberCategory.setId(ID); + existsClearingMemberCategory.setClearingMemberCategory("0000"); + existsClearingMemberCategory.setCompanyId(COMPANY_ID); + memberCategoryImdg.insert(existsClearingMemberCategory); ClearingMemberCategoryUpdateRequest memberCategoryUpdateRequest = new ClearingMemberCategoryUpdateRequest(); memberCategoryUpdateRequest.setId(ID); memberCategoryUpdateRequest.setClearingMemberCategory(clearingMemberCategory); ClearingMemberCategory predictableClearingMemberCategory = new ClearingMemberCategory(); + predictableClearingMemberCategory.setCompanyId(COMPANY_ID); predictableClearingMemberCategory.setId(ID); predictableClearingMemberCategory.setClearingMemberCategory(clearingMemberCategory); @@ -130,10 +168,10 @@ class ClearingMemberCategoryServiceTest { void clearingMemberCategoryDelete() throws InterruptedException { //ARRANGE String clearingMemberCategory = "0000"; - ClearingMemberCategory existsСlearingMemberCategory = new ClearingMemberCategory(); - existsСlearingMemberCategory.setId(ID); - existsСlearingMemberCategory.setClearingMemberCategory(clearingMemberCategory); - memberCategoryImdg.insert(existsСlearingMemberCategory); + ClearingMemberCategory existsClearingMemberCategory = new ClearingMemberCategory(); + existsClearingMemberCategory.setId(ID); + existsClearingMemberCategory.setClearingMemberCategory(clearingMemberCategory); + memberCategoryImdg.insert(existsClearingMemberCategory); CommonDeleteRequest memberCategoryDeleteRequest = new CommonDeleteRequest(); memberCategoryDeleteRequest.setId(ID); From 536df6a156af5206bc11e0f708ccd40955fd5ad4 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Mon, 3 Apr 2023 21:08:25 +0300 Subject: [PATCH 15/90] =?UTF-8?q?platform-messaging=20-=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D1=8B=D0=B5=20=D1=82=D1=80=D0=B5=D0=B1=D1=83=D0=B5?= =?UTF-8?q?=D0=BC=D1=8B=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../messaging/domain/BaseRequest.java | 14 ++++++++++++ .../domain/cud/company/CompanyNewRequest.java | 22 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/BaseRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/BaseRequest.java index 9e61b491f..5672500aa 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/BaseRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/BaseRequest.java @@ -20,6 +20,12 @@ public class BaseRequest implements WithId { @JsonProperty private T requestPayload; + /** + * ID пользователя, приславшего запрос. + */ + @JsonProperty + private Long userId; + @Override public Long getId() { return id; @@ -44,4 +50,12 @@ public class BaseRequest implements WithId { public void setRequestPayload(T requestPayload) { this.requestPayload = (T) requestPayload; } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java index a3796192e..fa0c2a46a 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java @@ -14,6 +14,12 @@ public class CompanyNewRequest { @JsonProperty private String registrationCode; + // for update, todo разобраться, это тот же тип запроса или надо отдельный на update сделать? + @JsonProperty + private Long id; + @JsonProperty + private String workflowStatus; + public String getShortName() { return shortName; } @@ -53,4 +59,20 @@ public class CompanyNewRequest { public void setRegistrationCode(String registrationCode) { this.registrationCode = registrationCode; } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } } From f334a31b101be4afe4eb4df5b9e036b390b85e23 Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 4 Apr 2023 11:29:09 +0300 Subject: [PATCH 16/90] EndDtAfterStartDtRule --- .../common/rules/EndDtAfterStartDtRule.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java new file mode 100644 index 000000000..23095ca69 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java @@ -0,0 +1,86 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.time.LocalDate; +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка EndDt < StartDt + * @param Класс проверяемого объекта + */ +public record EndDtAfterStartDtRule( + String endDtFieldName, + String startDtFieldName, + Function getterEndDt, + Function getterStartDt, + IEnumId errorEmptyRequiredValue, + IEnumId errorEndDtAfterStartDt, + boolean required +) implements IValidationRule> { + + /** + * @param endDtFieldName Название поля класса, содержащий EndDt + * @param startDtFieldName Название поля класса, содержащий StartDt + * @param getterEndDt Метод получения проверяемой EndDt + * @param getterStartDt Метод получения проверяемой StartDt + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если одна из дат пустая + * @param errorEndDtAfterStartDt Ошибка, которая будет возвращена, если EndDt > StartDt + * @param required Флаг обязательности поля + * @param Класс проверяемого объекта + */ + public static EndDtAfterStartDtRule instance(String endDtFieldName, + String startDtFieldName, + Function getterEndDt, + Function getterStartDt, + IEnumId errorEmptyRequiredValue, + IEnumId errorEndDtAfterStartDt, + boolean required) { + return new EndDtAfterStartDtRule<>(endDtFieldName, + startDtFieldName, + getterEndDt, + getterStartDt, + errorEmptyRequiredValue, + errorEndDtAfterStartDt, + required); + } + + /** + * @param endDtFieldName Название поля класса, содержащий EndDt + * @param startDtFieldName Название поля класса, содержащий StartDt + * @param getterEndDt Метод получения проверяемой EndDt + * @param getterStartDt Метод получения проверяемой StartDt + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если одна из дат пустая + * @param errorEndDtAfterStartDt Ошибка, которая будет возвращена, если EndDt > StartDt + * @param Класс проверяемого объекта + */ + public static EndDtAfterStartDtRule instance(String endDtFieldName, + String startDtFieldName, + Function getterEndDt, + Function getterStartDt, + IEnumId errorEmptyRequiredValue, + IEnumId errorEndDtAfterStartDt) { + return new EndDtAfterStartDtRule<>(endDtFieldName, + startDtFieldName, + getterEndDt, + getterStartDt, + errorEmptyRequiredValue, + errorEndDtAfterStartDt, + true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + LocalDate endDt = getterEndDt.apply(validatedObject); + LocalDate startDt = getterStartDt.apply(validatedObject); + if (endDt == null) return required ? of(errorEmptyRequiredValue, endDtFieldName) : Optional.empty(); + if (startDt == null) return required ? of(errorEmptyRequiredValue, startDtFieldName) : Optional.empty(); + if (endDt.isAfter(startDt)) return of(errorEndDtAfterStartDt); + return Optional.empty(); + } +} From 7eb629f158fa792b178e93e8d8fa3cdb8add71d5 Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 4 Apr 2023 11:32:30 +0300 Subject: [PATCH 17/90] profileDocumentNewRequestValidator --- .../common/rules/EndDtAfterStartDtRule.java | 2 +- .../ProfileDocumentValidationConfig.java | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java index 23095ca69..909dc97e8 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java @@ -80,7 +80,7 @@ public record EndDtAfterStartDtRule( LocalDate startDt = getterStartDt.apply(validatedObject); if (endDt == null) return required ? of(errorEmptyRequiredValue, endDtFieldName) : Optional.empty(); if (startDt == null) return required ? of(errorEmptyRequiredValue, startDtFieldName) : Optional.empty(); - if (endDt.isAfter(startDt)) return of(errorEndDtAfterStartDt); + if (endDt.isAfter(startDt)) return of(errorEndDtAfterStartDt, startDtFieldName, endDtFieldName); return Optional.empty(); } } 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 new file mode 100644 index 000000000..00024133f --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java @@ -0,0 +1,82 @@ +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.platform.dictionary.DocumentTypeDictionary; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentNewRequest; +import ru.spcex.clearing.validation.common.rules.*; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.enumeration.DocumentTypes; +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 ProfileDocumentValidationConfig { + + @Bean("profileDocumentNewRequestValidation") + public Function profileDocumentNewRequestValidator( + Map> imdgForValidation + ) { + return profileDocumentNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(profileDocumentNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary); + addImdg.accept(IMDGDistributedNames.Map_ProfileDocument); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + ProfileDocumentNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound, + company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), + EnumPresentRule.instance("documentType", + ProfileDocumentNewRequest::getDocumentType, + DocumentTypes.values(), + CompanyErrors.WrongFieldValue, + CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("documentType", + ProfileDocumentNewRequest::getDocumentType, + IMDGDistributedNames.Map_DocumentTypeDictionary, + DocumentTypeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue), + FieldRequiredRule.instance("issueDate", + ProfileDocumentNewRequest::getIssueDate, + CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("issuer", + ProfileDocumentNewRequest::getIssuer, + CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("issuerCode", + ProfileDocumentNewRequest::getIssuerCode, + CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("name", + ProfileDocumentNewRequest::getName, + CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("number", + ProfileDocumentNewRequest::getNumber, + CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("place", + ProfileDocumentNewRequest::getPlace, + CompanyErrors.RequiredFieldEmpty), + EndDtAfterStartDtRule.instance("validFromDate", "validToDate", + ProfileDocumentNewRequest::getValidFromDate, + ProfileDocumentNewRequest::getValidToDate, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue) + ); + }; + } +} From dcb517d300aa6de9654c90391a8ff808e0fec55d Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 4 Apr 2023 12:09:22 +0300 Subject: [PATCH 18/90] profileDocumentNewRequest --- .../config/validation/ValidationConfig.java | 4 ++ .../service/ProfileDocumentService.java | 40 ++++++++++++++----- .../service/ProfileDocumentServiceTest.java | 40 ++++++++++++++++--- 3 files changed, 69 insertions(+), 15 deletions(-) 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 617eceff3..9ce392c5d 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 @@ -4,7 +4,9 @@ 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.generated.ClearingMemberCategory; +import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.platform.dictionary.DocumentTypeDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -27,6 +29,8 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary, ClearingCategoryDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary, DocumentTypeDictionary.class); return imdg; } 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 28990c9f5..a5deb9f63 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 @@ -6,7 +6,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.lang.NonNull; +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.imdg.IMDGDistributedNames; @@ -14,10 +16,17 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentNewRequest; 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.DocumentTypes; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.validation.IValidator; +import java.util.function.Function; + +@Service public class ProfileDocumentService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private Imdg profileDocumentMap; @@ -25,14 +34,21 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin private ImdgProvider imdgProvider; private KafkaSender kafkaReqProducer; + private final Function profileDocumentNewRequestValidator; + private final ValidationHelper validationHelper; + @Autowired public ProfileDocumentService(Consumer kafkaQueue, Producer kafkaProducer, KafkaSender kafkaReqProducer, - ImdgProvider imdgProvider) { + ImdgProvider imdgProvider, + @Qualifier("profileDocumentNewRequestValidation") Function profileDocumentNewRequestValidator, + ValidationHelper validationHelper) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; this.kafkaReqProducer = kafkaReqProducer; + this.profileDocumentNewRequestValidator = profileDocumentNewRequestValidator; + this.validationHelper = validationHelper; } @Override @@ -41,20 +57,22 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); callback(ProfileDocumentNewRequest.class) - .setConsumer(this::newProfileDocument) + .setConsumer(this::profileDocumentNew) .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); init(); } @NonNull - private void newProfileDocument(BaseRequest profileDocumentNewRequestBaseRequest) { + private RequestInfoUpdate profileDocumentNew(BaseRequest profileDocumentNewRequestBaseRequest) { log.trace("Start processing ProfileDocumentNewRequest!"); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( + profileDocumentNewRequestBaseRequest, + profileDocumentNewRequestValidator + ); + if (requestInfoUpdate != null) return requestInfoUpdate; + ProfileDocumentNewRequest profileDocumentNewRequest = profileDocumentNewRequestBaseRequest.getRequestPayload(); - Long companyId = profileDocumentNewRequest.getCompanyId(); - Company company = companyMap.getSingleObjectByID(companyId); - if (company != null && !company.getWorkflowStatus().equalsIgnoreCase("ACTV")) { - throw new IllegalStateException("Wrong company with ID " + companyId + " and workflow status " + company.getWorkflowStatus()); - } ProfileDocument profileDocument = new ProfileDocument(); profileDocument.setCompanyId(profileDocumentNewRequest.getCompanyId()); profileDocument.setDocumentType(profileDocumentNewRequest.getDocumentType()); @@ -69,9 +87,11 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin profileDocument.setValidToDate(profileDocumentNewRequest.getValidToDate()); profileDocument.setLink(profileDocumentNewRequest.getLink()); profileDocumentMap.insert(profileDocument); - if (profileDocument.getDocumentType().equalsIgnoreCase("XCNT")) { - //kafkaReqProducer.sendRequestToQueue(Consts.EXPORT_PROCESS, exportRequest); + if (profileDocument.getDocumentType().equalsIgnoreCase(DocumentTypes.xcnt.getKey())) { +// kafkaReqProducer.sendRequestToQueue(Consts.EXPORT_PROCESS, exportRequest); } + + return null; } } diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java index 491212001..89d058cef 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java @@ -14,18 +14,25 @@ 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.profile.ProfileDocument; +import ru.clearing.platform.dictionary.DocumentTypeDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.ProfileDocumentValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; 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.company.ProfileDocumentNewRequest; +import ru.spcex.platform.enumeration.DocumentTypes; +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 java.time.LocalDate; +import java.time.temporal.ChronoUnit; import static ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration.currentID; import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; @@ -33,8 +40,11 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, ProfileDocumentService.class, KafkaConfigTest.class, + ProfileDocumentValidationConfig.class, HazelcastServiceTestConfiguration.class}) class ProfileDocumentServiceTest { @@ -55,11 +65,32 @@ class ProfileDocumentServiceTest { @SpyBean private MockProducer mockProducer; + private final long COMPANY_ID = 777L; + private Company TEST_COMPANY; + + private DocumentTypes TEST_DOCUMENT_TYPE = DocumentTypes.cio; + private String TEST_DOCUMENT_TYPE_ID = TEST_DOCUMENT_TYPE.getKey(); + @PostConstruct private void init() { hazelcastServiceTest.waitAvailable(); this.profileDocumentMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); this.companyMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + TEST_COMPANY = new Company(); + TEST_COMPANY.setId(COMPANY_ID); + TEST_COMPANY.setWorkflowStatus(WorkflowStatus.Active.getKey()); + companyMap.insert(TEST_COMPANY); + + DocumentTypeDictionary documentTypeDictionary = new DocumentTypeDictionary(); + documentTypeDictionary.setCode(TEST_DOCUMENT_TYPE.getKey()); + documentTypeDictionary.setName("test_name"); + Imdg documentTypeDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_DocumentTypeDictionary, + DocumentTypeDictionary.class + ); + documentTypeDictionaryImdg.insert(documentTypeDictionary); + } /** @@ -70,10 +101,9 @@ class ProfileDocumentServiceTest { @Test void newProfileDocument() { //ARRANGE - Long companyId = 1234L; ProfileDocumentNewRequest profileDocumentNewRequest = new ProfileDocumentNewRequest(); - profileDocumentNewRequest.setCompanyId(companyId); - profileDocumentNewRequest.setDocumentType("doc"); + profileDocumentNewRequest.setCompanyId(COMPANY_ID); + profileDocumentNewRequest.setDocumentType(TEST_DOCUMENT_TYPE_ID); profileDocumentNewRequest.setIssueDate(LocalDate.now()); profileDocumentNewRequest.setIssuePlace("place"); profileDocumentNewRequest.setIssuer("issuer"); @@ -82,7 +112,7 @@ class ProfileDocumentServiceTest { profileDocumentNewRequest.setNumber("number"); profileDocumentNewRequest.setPlace("place"); profileDocumentNewRequest.setValidFromDate(LocalDate.now()); - profileDocumentNewRequest.setValidToDate(LocalDate.now()); + profileDocumentNewRequest.setValidToDate(LocalDate.now().plus(1, ChronoUnit.DAYS)); profileDocumentNewRequest.setLink("link"); ProfileDocument predictableProfileDocument = new ProfileDocument(); @@ -106,7 +136,7 @@ class ProfileDocumentServiceTest { //ASSERT waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); - ProfileDocument resultNew = profileDocumentMap.getSingleObjectBySQL(String.format("companyId = %d", companyId)); + ProfileDocument resultNew = profileDocumentMap.getSingleObjectBySQL(String.format("companyId = %d", COMPANY_ID)); predictableProfileDocument.setId(resultNew.getId()); PROFILE_DOCUMENT_MATCHER.assertMatch(resultNew, predictableProfileDocument); } From 93664b6ef51e32f7b8b9e2748ee92f9ec0f41d7b Mon Sep 17 00:00:00 2001 From: psemenkov Date: Tue, 4 Apr 2023 13:37:03 +0300 Subject: [PATCH 19/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20MoneyMark?= =?UTF-8?q?etSecurityMapStore.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/clearing/classes/statics/data/security/Security.java | 3 ++- .../clearing/imdg/businessobject/EquitySecurityMapStore.java | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java index d9d153dc2..038e39b40 100644 --- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java @@ -2,13 +2,14 @@ package ru.clearing.classes.statics.data.security; import ru.clearing.classes.ConstSerializable; import ru.clearing.classes.objects.BusinessObject; +import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; /** * Инструменты *

* DB table: SECURITY **/ -public class Security extends BusinessObject { +public class Security extends BusinessObject implements WithWorkflowStatus { private static final long serialVersionUID = ConstSerializable.serialVersionUID; private String instrumentType; diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java index 24cb7ac06..c6d21f3f2 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/EquitySecurityMapStore.java @@ -7,7 +7,6 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.base.TemplateMapStore; import ru.spcex.platform.utils.time.TimeUtil; -import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; @@ -34,7 +33,7 @@ public class EquitySecurityMapStore extends TemplateMapStore { @Override public String[] getFields() { return new String[]{ - "ID", "SECURITY_ID", "SHARE_TYPE", "LOT_SIZE" + "ID", "SECURITY_ID", "SHARE_TYPE"//, "LOT_SIZE" }; } @@ -58,7 +57,7 @@ public class EquitySecurityMapStore extends TemplateMapStore { object.setId(resultSet.getObject("ID", Long.class)); object.setSecurityId(resultSet.getObject("SECURITY_ID", Long.class)); object.setShareType(resultSet.getObject("SHARE_TYPE", String.class)); - object.setLotSize(resultSet.getObject("LOT_SIZE", BigDecimal.class)); +// object.setLotSize(resultSet.getObject("LOT_SIZE", BigDecimal.class)); fillBySecurity(object, object.getSecurityId()); return object; } From 53a5d25cd9fc3487982e4b776b02d14a7dce677e Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 4 Apr 2023 14:49:41 +0300 Subject: [PATCH 20/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-259?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20platform-enum,?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8F=20=D0=B2=20CompanyNewRequest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/enumeration/CompanySymbol.java | 3 ++- .../platform/enumeration/ServiceProduct.java | 20 ++++++++++++++ .../platform/messaging/domain/Consts.java | 1 + .../domain/cud/company/CompanyNewRequest.java | 27 +++++++++++++++++-- 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ServiceProduct.java diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java index 33170c8d0..fe03542c9 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java @@ -3,7 +3,8 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum CompanySymbol implements IEnumKey { - INN("INN"), BIC("BIC"); + INN("INN"), BIC("BIC"), + TRDC("TRDC"), CLRC("CLRC"), RGRC("RGRC"); private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ServiceProduct.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ServiceProduct.java new file mode 100644 index 000000000..7272851d8 --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ServiceProduct.java @@ -0,0 +1,20 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum ServiceProduct implements IEnumKey { + PRNT("PRNT"), // Расчет обязательств с процентом + ZERO("ZERO") // Расчет обязательств без процента (по умолчанию) + ; + + private final String key; + + ServiceProduct(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 44d11db48..377059b1d 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 @@ -24,6 +24,7 @@ public interface Consts { String DESTINATION_COMPANY_NEW = "company-new"; String DESTINATION_COMPANY_DELETE = "company-delete"; String DESTINATION_COMPANY_UPDATE = "company-update"; + String DESTINATION_COMPANY_BLOCK = "company-block"; String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update"; String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update"; String DESTINATION_CONTACT_UPDATE = "contact-update"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java index fa0c2a46a..79685bd20 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java @@ -7,6 +7,15 @@ public class CompanyNewRequest { private String shortName; @JsonProperty private String fullName; + + @JsonProperty + private String companySymbol; + @JsonProperty + private String companySymbolValue; + @JsonProperty + private String workflowStatus; + + //todo deprecated 3 field: @JsonProperty private String tradingCode; @JsonProperty @@ -17,8 +26,6 @@ public class CompanyNewRequest { // for update, todo разобраться, это тот же тип запроса или надо отдельный на update сделать? @JsonProperty private Long id; - @JsonProperty - private String workflowStatus; public String getShortName() { return shortName; @@ -60,6 +67,22 @@ public class CompanyNewRequest { this.registrationCode = registrationCode; } + public String getCompanySymbol() { + return companySymbol; + } + + public void setCompanySymbol(String companySymbol) { + this.companySymbol = companySymbol; + } + + public String getCompanySymbolValue() { + return companySymbolValue; + } + + public void setCompanySymbolValue(String companySymbolValue) { + this.companySymbolValue = companySymbolValue; + } + public Long getId() { return id; } From 7d0da57d4a2511d87156d99fd456231e5cc75197 Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 4 Apr 2023 15:06:36 +0300 Subject: [PATCH 21/90] ProfileDocumentUpdateRequest --- .../platform/messaging/domain/Consts.java | 1 + .../company/ProfileDocumentUpdateRequest.java | 148 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ProfileDocumentUpdateRequest.java 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 377059b1d..c4479c5a9 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 @@ -37,6 +37,7 @@ public interface Consts { String DESTINATION_BANK_ACCOUNT_NEW = "bank-account-new"; String DESTINATION_RELATION_UPDATE = "relation-update"; String DESTINATION_PROFILE_DOCUMENT_NEW = "profile-document-new"; + String DESTINATION_PROFILE_DOCUMENT_UPDATE = "profile-document-update"; 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/company/ProfileDocumentUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ProfileDocumentUpdateRequest.java new file mode 100644 index 000000000..c91937e63 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ProfileDocumentUpdateRequest.java @@ -0,0 +1,148 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; + +import java.time.LocalDate; + +public class ProfileDocumentUpdateRequest { + @JsonProperty + private Long id; + @JsonProperty + private Long companyId; + @JsonProperty + private String documentType; + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonProperty + private LocalDate issueDate; + @JsonProperty + private String issuePlace; + @JsonProperty + private String issuer; + @JsonProperty + private String issuerCode; + @JsonProperty + private String name; + @JsonProperty + private String number; + @JsonProperty + private String place; + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonProperty + private LocalDate validFromDate; + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonProperty + private LocalDate validToDate; + @JsonProperty + private String link; + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public String getDocumentType() { + return documentType; + } + + public void setDocumentType(String documentType) { + this.documentType = documentType; + } + + public LocalDate getIssueDate() { + return issueDate; + } + + public void setIssueDate(LocalDate issueDate) { + this.issueDate = issueDate; + } + + public String getIssuePlace() { + return issuePlace; + } + + public void setIssuePlace(String issuePlace) { + this.issuePlace = issuePlace; + } + + public String getIssuer() { + return issuer; + } + + public void setIssuer(String issuer) { + this.issuer = issuer; + } + + public String getIssuerCode() { + return issuerCode; + } + + public void setIssuerCode(String issuerCode) { + this.issuerCode = issuerCode; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getPlace() { + return place; + } + + public void setPlace(String place) { + this.place = place; + } + + public LocalDate getValidFromDate() { + return validFromDate; + } + + public void setValidFromDate(LocalDate validFromDate) { + this.validFromDate = validFromDate; + } + + public LocalDate getValidToDate() { + return validToDate; + } + + public void setValidToDate(LocalDate validToDate) { + this.validToDate = validToDate; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} From 30485d7104c6823a06563b65c9d0430e0cbe832a Mon Sep 17 00:00:00 2001 From: psemenkov Date: Tue, 4 Apr 2023 15:51:46 +0300 Subject: [PATCH 22/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../statics/data/security/Security.java | 3 +- .../imdg/validation/rule/PresentById.java | 3 + .../platform/messaging/domain/Consts.java | 8 + .../FixedIncomeSecurityNewRequest.java | 178 ++++++++++++++++ .../FixedIncomeSecurityUpdateRequest.java | 190 ++++++++++++++++++ 5 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java index 038e39b40..b962fd9a8 100644 --- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/security/Security.java @@ -2,6 +2,7 @@ package ru.clearing.classes.statics.data.security; import ru.clearing.classes.ConstSerializable; import ru.clearing.classes.objects.BusinessObject; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; /** @@ -9,7 +10,7 @@ import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; *

* DB table: SECURITY **/ -public class Security extends BusinessObject implements WithWorkflowStatus { +public class Security extends BusinessObject implements WithWorkflowStatus, WithInstrumentType { private static final long serialVersionUID = ConstSerializable.serialVersionUID; private String instrumentType; diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java index a69cab7b9..824f0acea 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java @@ -29,6 +29,9 @@ public class PresentById implements IValidationRule validate(ImdgValidationContext context) { WithId actionById = context.getValidatedObject(); + if (actionById.getId() == null) { + return of(errorEnum, actionById.getId()); + } Imdg targetMap = context.obtainMap(mapName, SpcexObjectBase.class); SpcexObjectBase obj = targetMap.getSingleObjectByID(actionById.getId()); if (obj == null) { 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 c4479c5a9..7e768cc99 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 @@ -5,6 +5,14 @@ public interface Consts { String DESTINATION_MONEY_MARKET_SECURITY_UPDATE = "money-market-security-update"; String DESTINATION_MONEY_MARKET_SECURITY_DELETE = "money-market-security-delete"; + String DESTINATION_EQUITY_SECURITY_NEW = "equity-security-new"; + String DESTINATION_EQUITY_SECURITY_UPDATE = "equity-security-update"; + String DESTINATION_EQUITY_SECURITY_DELETE = "equity-security-delete"; + + String DESTINATION_FIXED_INCOME_SECURITY_NEW = "fixed-income-security-new"; + String DESTINATION_FIXED_INCOME_SECURITY_UPDATE = "fixed-income-security-update"; + String DESTINATION_FIXED_INCOME_SECURITY_DELETE = "fixed-income-security-delete"; + String DESTINATION_KEY_RATE_NEW = "key-rate-new"; String DESTINATION_KEY_RATE_UPDATE = "key-rate-update"; String DESTINATION_KEY_RATE_DELETE = "key-rate-delete"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java new file mode 100644 index 000000000..c39fcb494 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java @@ -0,0 +1,178 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; +import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; + +import java.time.LocalDate; + +public class FixedIncomeSecurityNewRequest implements WithSecuritySymbol, WithInstrumentType { + @JsonProperty + public String securitySymbol; + @JsonProperty + public String shortName; + @JsonProperty + public String fullName; + @JsonProperty + public String isin; + @JsonProperty + public String bondType; + @JsonProperty + public Double lotSize; + @JsonProperty + public Double nominalValue; + @JsonProperty + public String nominalCurrency; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate maturityDate; + @JsonProperty + public Double coupon; + @JsonProperty + public Long couponFrequency; + @JsonProperty + public Long issuerId; + @JsonProperty + public String shortNameEng; + @JsonProperty + public String fullNameEng; + @JsonProperty + public String workflowStatus; + @JsonProperty + public String instrumentType; + + @Override + public String getSecuritySymbol() { + return securitySymbol; + } + + public void setSecuritySymbol(String securitySymbol) { + this.securitySymbol = securitySymbol; + } + + 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 getIsin() { + return isin; + } + + public void setIsin(String isin) { + this.isin = isin; + } + + public String getBondType() { + return bondType; + } + + public void setBondType(String bondType) { + this.bondType = bondType; + } + + public Double getLotSize() { + return lotSize; + } + + public void setLotSize(Double lotSize) { + this.lotSize = lotSize; + } + + public Double getNominalValue() { + return nominalValue; + } + + public void setNominalValue(Double nominalValue) { + this.nominalValue = nominalValue; + } + + public String getNominalCurrency() { + return nominalCurrency; + } + + public void setNominalCurrency(String nominalCurrency) { + this.nominalCurrency = nominalCurrency; + } + + public LocalDate getMaturityDate() { + return maturityDate; + } + + public void setMaturityDate(LocalDate maturityDate) { + this.maturityDate = maturityDate; + } + + public Double getCoupon() { + return coupon; + } + + public void setCoupon(Double coupon) { + this.coupon = coupon; + } + + public Long getCouponFrequency() { + return couponFrequency; + } + + public void setCouponFrequency(Long couponFrequency) { + this.couponFrequency = couponFrequency; + } + + public Long getIssuerId() { + return issuerId; + } + + public void setIssuerId(Long issuerId) { + this.issuerId = issuerId; + } + + 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 getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } + + @Override + public String getInstrumentType() { + return instrumentType; + } + + public void setInstrumentType(String instrumentType) { + this.instrumentType = instrumentType; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java new file mode 100644 index 000000000..dcfd798ea --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java @@ -0,0 +1,190 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; +import ru.spcex.platform.classes.base.interfaces.WithId; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; +import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; + +import java.time.LocalDate; + +public class FixedIncomeSecurityUpdateRequest implements WithId, WithInstrumentType, WithWorkflowStatus { + @JsonProperty + public Long id; + @JsonProperty + public String securitySymbol; + @JsonProperty + public String shortName; + @JsonProperty + public String fullName; + @JsonProperty + public String isin; + @JsonProperty + public String bondType; + @JsonProperty + public Double lotSize; + @JsonProperty + public Double nominalValue; + @JsonProperty + public String nominalCurrency; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate maturityDate; + @JsonProperty + public Double coupon; + @JsonProperty + public Long couponFrequency; + @JsonProperty + public Long issuerId; + @JsonProperty + public String shortNameEng; + @JsonProperty + public String fullNameEng; + @JsonProperty + public String workflowStatus; + @JsonProperty + public String instrumentType; + + @Override + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getSecuritySymbol() { + return securitySymbol; + } + + public void setSecuritySymbol(String securitySymbol) { + this.securitySymbol = securitySymbol; + } + + 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 getIsin() { + return isin; + } + + public void setIsin(String isin) { + this.isin = isin; + } + + public String getBondType() { + return bondType; + } + + public void setBondType(String bondType) { + this.bondType = bondType; + } + + public Double getLotSize() { + return lotSize; + } + + public void setLotSize(Double lotSize) { + this.lotSize = lotSize; + } + + public Double getNominalValue() { + return nominalValue; + } + + public void setNominalValue(Double nominalValue) { + this.nominalValue = nominalValue; + } + + public String getNominalCurrency() { + return nominalCurrency; + } + + public void setNominalCurrency(String nominalCurrency) { + this.nominalCurrency = nominalCurrency; + } + + public LocalDate getMaturityDate() { + return maturityDate; + } + + public void setMaturityDate(LocalDate maturityDate) { + this.maturityDate = maturityDate; + } + + public Double getCoupon() { + return coupon; + } + + public void setCoupon(Double coupon) { + this.coupon = coupon; + } + + public Long getCouponFrequency() { + return couponFrequency; + } + + public void setCouponFrequency(Long couponFrequency) { + this.couponFrequency = couponFrequency; + } + + public Long getIssuerId() { + return issuerId; + } + + public void setIssuerId(Long issuerId) { + this.issuerId = issuerId; + } + + 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; + } + + @Override + public String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } + + @Override + public String getInstrumentType() { + return instrumentType; + } + + public void setInstrumentType(String instrumentType) { + this.instrumentType = instrumentType; + } +} From adf57e7b00b3451e1266b0090aafd7933a391551 Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 4 Apr 2023 15:56:24 +0300 Subject: [PATCH 23/90] updateProfileDocument --- .../common/rules/DictionaryPresentRule.java | 2 +- ...learingMemberCategoryValidationConfig.java | 4 +- .../ProfileDocumentValidationConfig.java | 51 ++++++++++++ .../service/ProfileDocumentService.java | 76 ++++++++++++++++- .../service/ProfileDocumentServiceTest.java | 83 ++++++++++++++++++- 5 files changed, 207 insertions(+), 9 deletions(-) diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java index 67b6586c9..8fed6e5ed 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -48,8 +48,8 @@ public record DictionaryPresentRule(String fiel getter, dictionaryName, dictionaryClass, - errorWrongDictionaryValue, errorEmptyRequiredValue, + errorWrongDictionaryValue, required); } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java index c41e4283d..d1c44aa66 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java @@ -84,6 +84,7 @@ public class ClearingMemberCategoryValidationConfig { EnumPresentRule.instance("clearingMemberCategory", ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, ClearingCategory.values(), + false, CompanyErrors.WrongFieldValue, CompanyErrors.RequiredFieldEmpty), DictionaryPresentRule.instance("clearingMemberCategory", @@ -91,7 +92,8 @@ public class ClearingMemberCategoryValidationConfig { IMDGDistributedNames.Map_ClearingCategoryDictionary, ClearingCategoryDictionary.class, CompanyErrors.RequiredFieldEmpty, - CompanyErrors.WrongFieldValue)); + CompanyErrors.WrongFieldValue, + false)); }; } 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 00024133f..7dbbc420a 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 @@ -3,10 +3,12 @@ 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.profile.ProfileDocument; import ru.clearing.platform.dictionary.DocumentTypeDictionary; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; import ru.spcex.clearing.validation.common.rules.*; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.DocumentTypes; @@ -79,4 +81,53 @@ public class ProfileDocumentValidationConfig { ); }; } + + @Bean("profileDocumentUpdateRequestValidation") + public Function profileDocumentUpdateRequestValidator( + Map> imdgForValidation + ) { + return profileDocumentUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(profileDocumentUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary); + addImdg.accept(IMDGDistributedNames.Map_ProfileDocument); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + ProfileDocumentUpdateRequest::getId, + IMDGDistributedNames.Map_ProfileDocument, + ProfileDocument.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RecordNotFound), + IdPresentRule.instance("companyId", + ProfileDocumentUpdateRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound, + false, + company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), + EnumPresentRule.instance("documentType", + ProfileDocumentUpdateRequest::getDocumentType, + DocumentTypes.values(), + false, + CompanyErrors.WrongFieldValue, + CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("documentType", + ProfileDocumentUpdateRequest::getDocumentType, + IMDGDistributedNames.Map_DocumentTypeDictionary, + DocumentTypeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false), + EndDtAfterStartDtRule.instance("validFromDate", "validToDate", + ProfileDocumentUpdateRequest::getValidFromDate, + ProfileDocumentUpdateRequest::getValidToDate, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false) + ); + }; + } } 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 a5deb9f63..8204af83a 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 @@ -15,11 +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.company.ProfileDocumentNewRequest; +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.validation.common.ValidationHelper; -import ru.spcex.platform.enumeration.DocumentTypes; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.validation.IValidator; @@ -35,6 +35,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin private KafkaSender kafkaReqProducer; private final Function profileDocumentNewRequestValidator; + private final Function profileDocumentUpdateRequestValidator; private final ValidationHelper validationHelper; @Autowired @@ -43,11 +44,13 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin KafkaSender kafkaReqProducer, ImdgProvider imdgProvider, @Qualifier("profileDocumentNewRequestValidation") Function profileDocumentNewRequestValidator, + @Qualifier("profileDocumentUpdateRequestValidation") Function profileDocumentUpdateRequestValidator, ValidationHelper validationHelper) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; this.kafkaReqProducer = kafkaReqProducer; this.profileDocumentNewRequestValidator = profileDocumentNewRequestValidator; + this.profileDocumentUpdateRequestValidator = profileDocumentUpdateRequestValidator; this.validationHelper = validationHelper; } @@ -59,6 +62,9 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin callback(ProfileDocumentNewRequest.class) .setConsumer(this::profileDocumentNew) .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); + callback(ProfileDocumentUpdateRequest.class) + .setConsumer(this::profileDocumentUpdate) + .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE, callbacks::put); init(); } @@ -88,9 +94,71 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin profileDocument.setLink(profileDocumentNewRequest.getLink()); profileDocumentMap.insert(profileDocument); - if (profileDocument.getDocumentType().equalsIgnoreCase(DocumentTypes.xcnt.getKey())) { -// kafkaReqProducer.sendRequestToQueue(Consts.EXPORT_PROCESS, exportRequest); - } +// if (profileDocument.getDocumentType().equalsIgnoreCase(DocumentTypes.xcnt.getKey())) { + // todo create request for update and check request for new account (something wrong) +// kafkaReqProducer.sendRequestToQueue(Consts.ACCOUNT_UPDATE, ) +// } + + return null; + } + + @NonNull + private RequestInfoUpdate profileDocumentUpdate(BaseRequest profileDocumentUpdateRequestBaseRequest) { + log.trace("Start processing ProfileDocumentUpdateRequest!"); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( + profileDocumentUpdateRequestBaseRequest, + profileDocumentUpdateRequestValidator + ); + if (requestInfoUpdate != null) return requestInfoUpdate; + + ProfileDocumentUpdateRequest profileDocumentUpdateRequest = profileDocumentUpdateRequestBaseRequest.getRequestPayload(); + ProfileDocument profileDocument = profileDocumentMap.getSingleObjectByID(profileDocumentUpdateRequest.getId()); + + if (profileDocumentUpdateRequest.getCompanyId() != null) + profileDocument.setCompanyId(profileDocumentUpdateRequest.getCompanyId()); + + if (profileDocumentUpdateRequest.getDocumentType() != null) + profileDocument.setDocumentType(profileDocumentUpdateRequest.getDocumentType()); + + if (profileDocumentUpdateRequest.getIssueDate() != null) + profileDocument.setIssueDate(profileDocumentUpdateRequest.getIssueDate()); + + if (profileDocumentUpdateRequest.getIssuePlace() != null) + profileDocument.setIssuePlace(profileDocumentUpdateRequest.getIssuePlace()); + + if (profileDocumentUpdateRequest.getIssuer() != null) + profileDocument.setIssuer(profileDocumentUpdateRequest.getIssuer()); + + if (profileDocumentUpdateRequest.getIssuerCode() != null) + profileDocument.setIssuerCode(profileDocumentUpdateRequest.getIssuerCode()); + + if (profileDocumentUpdateRequest.getName() != null) + profileDocument.setName(profileDocumentUpdateRequest.getName()); + + if (profileDocumentUpdateRequest.getNumber() != null) + profileDocument.setNumber(profileDocumentUpdateRequest.getNumber()); + + if (profileDocumentUpdateRequest.getPlace() != null) + profileDocument.setPlace(profileDocumentUpdateRequest.getPlace()); + + if (profileDocumentUpdateRequest.getValidFromDate() != null) + profileDocument.setValidFromDate(profileDocumentUpdateRequest.getValidFromDate()); + + if (profileDocumentUpdateRequest.getValidToDate() != null) + profileDocument.setValidToDate(profileDocumentUpdateRequest.getValidToDate()); + + if (profileDocumentUpdateRequest.getLink() != null) + profileDocument.setLink(profileDocumentUpdateRequest.getLink()); + + profileDocumentMap.insert(profileDocument); + + log.trace("successfully processed, id {}", profileDocument.getId()); + +// if (profileDocument.getDocumentType().equalsIgnoreCase(DocumentTypes.xcnt.getKey())) { + // todo if update profileDocument with documentType == XCNT... need send? +// kafkaReqProducer.sendRequestToQueue(Consts.ACCOUNT_UPDATE, ) +// } return null; } diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java index 89d058cef..c2ed53986 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java @@ -25,6 +25,7 @@ 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.company.ProfileDocumentNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; import ru.spcex.platform.enumeration.DocumentTypes; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; @@ -51,6 +52,8 @@ class ProfileDocumentServiceTest { public static final MatcherFactory.Matcher PROFILE_DOCUMENT_MATCHER = usingIgnoringFieldsComparator(); private static final int PARTITION = 0; private static final String TOPIC_DESTINATION_PROFILE_DOCUMENT_NEW = Consts.DESTINATION_PROFILE_DOCUMENT_NEW; + private static final String TOPIC_DESTINATION_PROFILE_DOCUMENT_UPDATE = Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE; + private static final Long ID = currentID.getAndIncrement(); @Autowired ProfileDocumentService profileDocumentService; @@ -71,6 +74,11 @@ class ProfileDocumentServiceTest { private DocumentTypes TEST_DOCUMENT_TYPE = DocumentTypes.cio; private String TEST_DOCUMENT_TYPE_ID = TEST_DOCUMENT_TYPE.getKey(); + private DocumentTypes NEW_TEST_DOCUMENT_TYPE = DocumentTypes.edoc; + private String NEW_TEST_DOCUMENT_TYPE_ID = NEW_TEST_DOCUMENT_TYPE.getKey(); + + private final long PROFILE_DOCUMENT_ID = ID; + @PostConstruct private void init() { hazelcastServiceTest.waitAvailable(); @@ -82,15 +90,22 @@ class ProfileDocumentServiceTest { TEST_COMPANY.setWorkflowStatus(WorkflowStatus.Active.getKey()); companyMap.insert(TEST_COMPANY); - DocumentTypeDictionary documentTypeDictionary = new DocumentTypeDictionary(); - documentTypeDictionary.setCode(TEST_DOCUMENT_TYPE.getKey()); - documentTypeDictionary.setName("test_name"); Imdg documentTypeDictionaryImdg = hazelcastServiceTest.getImdg( IMDGDistributedNames.Map_DocumentTypeDictionary, DocumentTypeDictionary.class ); + + DocumentTypeDictionary documentTypeDictionary = new DocumentTypeDictionary(); + documentTypeDictionary.setCode(TEST_DOCUMENT_TYPE.getKey()); + documentTypeDictionary.setName("test_name"); documentTypeDictionaryImdg.insert(documentTypeDictionary); + DocumentTypeDictionary documentTypeDictionary1 = new DocumentTypeDictionary(); + documentTypeDictionary1.setCode(NEW_TEST_DOCUMENT_TYPE.getKey()); + documentTypeDictionary1.setName("new_test_name"); + documentTypeDictionaryImdg.insert(documentTypeDictionary1); + + } /** @@ -116,6 +131,7 @@ class ProfileDocumentServiceTest { profileDocumentNewRequest.setLink("link"); ProfileDocument predictableProfileDocument = new ProfileDocument(); + predictableProfileDocument.setId(PROFILE_DOCUMENT_ID); predictableProfileDocument.setCompanyId(profileDocumentNewRequest.getCompanyId()); predictableProfileDocument.setDocumentType(profileDocumentNewRequest.getDocumentType()); predictableProfileDocument.setIssueDate(profileDocumentNewRequest.getIssueDate()); @@ -140,4 +156,65 @@ class ProfileDocumentServiceTest { predictableProfileDocument.setId(resultNew.getId()); PROFILE_DOCUMENT_MATCHER.assertMatch(resultNew, predictableProfileDocument); } + + @Test + void updateProfileDocument() { + //ARRANGE + ProfileDocument existsProfileDocument = new ProfileDocument(); + existsProfileDocument.setId(ID); + existsProfileDocument.setCompanyId(COMPANY_ID); + existsProfileDocument.setDocumentType(TEST_DOCUMENT_TYPE_ID); + existsProfileDocument.setIssueDate(LocalDate.now()); + existsProfileDocument.setIssuePlace("place"); + existsProfileDocument.setIssuer("issuer"); + existsProfileDocument.setIssuerCode("issuerCode"); + existsProfileDocument.setName("name"); + existsProfileDocument.setNumber("number"); + existsProfileDocument.setPlace("place"); + existsProfileDocument.setValidFromDate(LocalDate.now()); + existsProfileDocument.setValidToDate(LocalDate.now().plus(1, ChronoUnit.DAYS)); + existsProfileDocument.setLink("link"); + profileDocumentMap.insert(existsProfileDocument); + + ProfileDocument predictableProfileDocument = new ProfileDocument(); + predictableProfileDocument.setId(PROFILE_DOCUMENT_ID); + predictableProfileDocument.setCompanyId(COMPANY_ID); + predictableProfileDocument.setDocumentType(NEW_TEST_DOCUMENT_TYPE_ID); + predictableProfileDocument.setIssueDate(LocalDate.now()); + predictableProfileDocument.setIssuePlace("new_place"); + predictableProfileDocument.setIssuer("new_issuer"); + predictableProfileDocument.setIssuerCode("new_issuerCode"); + predictableProfileDocument.setName("new_name"); + predictableProfileDocument.setNumber("new_number"); + predictableProfileDocument.setPlace("new_place"); + predictableProfileDocument.setValidFromDate(LocalDate.now()); + predictableProfileDocument.setValidToDate(LocalDate.now().plus(1, ChronoUnit.DAYS)); + predictableProfileDocument.setLink("new_link"); + + ProfileDocumentUpdateRequest profileDocumentUpdateRequest = new ProfileDocumentUpdateRequest(); + profileDocumentUpdateRequest.setId(PROFILE_DOCUMENT_ID); + profileDocumentUpdateRequest.setCompanyId(COMPANY_ID); + profileDocumentUpdateRequest.setDocumentType(NEW_TEST_DOCUMENT_TYPE_ID); + profileDocumentUpdateRequest.setIssueDate(LocalDate.now()); + profileDocumentUpdateRequest.setIssuePlace("new_place"); + profileDocumentUpdateRequest.setIssuer("new_issuer"); + profileDocumentUpdateRequest.setIssuerCode("new_issuerCode"); + profileDocumentUpdateRequest.setName("new_name"); + profileDocumentUpdateRequest.setNumber("new_number"); + profileDocumentUpdateRequest.setPlace("new_place"); + profileDocumentUpdateRequest.setValidFromDate(LocalDate.now()); + profileDocumentUpdateRequest.setValidToDate(LocalDate.now().plus(1, ChronoUnit.DAYS)); + profileDocumentUpdateRequest.setLink("new_link"); + + //ACT + String jsonString = getJsonStringForUPDATE(profileDocumentUpdateRequest, ID); + + addRecordToKafka((MockConsumer) profileDocumentService.getConsumer(), TOPIC_DESTINATION_PROFILE_DOCUMENT_UPDATE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + ProfileDocument resultUpdate = profileDocumentMap.getSingleObjectBySQL(String.format("companyId = %d", COMPANY_ID)); +// predictableProfileDocument.setId(resultUpdate.getId()); + PROFILE_DOCUMENT_MATCHER.assertMatch(resultUpdate, predictableProfileDocument); + } } \ No newline at end of file From 96dc0d031343208d8ffb40f6cc3199d5fc900462 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 4 Apr 2023 17:23:59 +0300 Subject: [PATCH 24/90] =?UTF-8?q?clearing-utils=20=D1=83=D0=BB=D1=83=D1=87?= =?UTF-8?q?=D1=88=D0=B8=D0=BB=20=D1=87=D0=B8=D1=82=D0=B0=D0=B5=D0=BC=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/clearing-utils/pom.xml | 5 +++-- .../validation/common/rules/DictionaryPresentRule.java | 5 +++++ .../clearing/validation/common/rules/EnumPresentRule.java | 5 +++++ .../clearing/validation/common/rules/FieldRequiredRule.java | 5 +++++ .../clearing/validation/common/rules/IdPresentRule.java | 5 +++++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-utils/pom.xml b/clearing-parent/clearing-utils/pom.xml index 4b9ecb09b..580382cc7 100644 --- a/clearing-parent/clearing-utils/pom.xml +++ b/clearing-parent/clearing-utils/pom.xml @@ -4,8 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - clearing-utils - Clearing-module, dependency version of platform-utils + clearing-utils + clearing-utils + Clearing-module, dependency version of platform-utils jar SPCEX-1.0.0.0 diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java index 8fed6e5ed..ab42f8bc0 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -99,4 +99,9 @@ public record DictionaryPresentRule(String fiel } return empty(); } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + " - " + dictionaryName + "}"; + } } diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java index a819a26e6..13a3494ff 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java @@ -69,4 +69,9 @@ public record EnumPresentRule(String fieldName, } return of(errorWrongEnumValue, fieldName); } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + "}"; + } } diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index 93473976a..2e215648e 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -40,4 +40,9 @@ public record FieldRequiredRule( if (value == null) return of(errorEmptyRequiredValue, fieldName); return empty(); } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + "}"; + } } diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java index 02db04c3e..5ce3c570f 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java @@ -103,4 +103,9 @@ public record IdPresentRule( } return empty(); } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + "}"; + } } From ba4a7140d6ab65239350473eb0dff68ae1c58877 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 4 Apr 2023 17:57:56 +0300 Subject: [PATCH 25/90] http://jira.mfd.msk:8088/browse/CLS-259 CompanyService --- .../company/config/BeanConfiguration.java | 7 + .../validation/CompanyValidationConfig.java | 94 ++++- .../config/validation/ValidationConfig.java | 4 + .../company/service/CompanyService.java | 343 +++++++++++++----- .../clearing/company/util/RequestHelper.java | 24 +- .../company/config/BeanConfiguration.java | 21 ++ .../company/service/CompanyServiceTest.java | 81 ++++- 7 files changed, 466 insertions(+), 108 deletions(-) create mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java 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 c77296e64..cec73efc2 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 @@ -2,6 +2,8 @@ package ru.spcex.clearing.company.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; @@ -11,4 +13,9 @@ public class BeanConfiguration { public IMessageResolver messageResolver() { return new SimpleMessageResolver(); } + + @Bean + UserRoleVerification userRoleVerification(ImdgProvider imdg) { + return new UserRoleVerification(imdg); + } } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java index 5c80d1569..2d3a63605 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java @@ -2,9 +2,19 @@ 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.platform.dictionary.CompanySymbolDictionary; +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.ClearingMemberCategoryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +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; @@ -23,24 +33,84 @@ public class CompanyValidationConfig { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(companyNewRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); -// addImdg.accept(IMDGDistributedNames.Map_TaskDictionary); -// addImdg.accept(IMDGDistributedNames.Map_TaskStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); addImdg.accept(IMDGDistributedNames.Map_Company); -// addImdg.accept(IMDGDistributedNames.Map_Security); return new ValidatorImpl<>(context - // , -// FieldRequiredRule.instance("shortName", CompanyNewRequest::getShortName, CompanyErrors.RequiredFieldEmpty), -// FieldRequiredRule.instance("companySymbol", CompanyNewRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), -// FieldRequiredRule.instance("companySymbolValue", CompanyNewRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), -// FieldRequiredRule.instance("workflowStatus", CompanyNewRequest::getWorkflowStatus, CompanyErrors.RequiredFieldEmpty), + , + FieldRequiredRule.instance("shortName", CompanyNewRequest::getShortName, CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("companySymbol", CompanyNewRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("companySymbolValue", CompanyNewRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("workflowStatus", CompanyNewRequest::getWorkflowStatus, CompanyErrors.RequiredFieldEmpty), -// DictionaryPresentRule.instance("workflowStatus", -// CompanyNewRequest::getWorkflowStatus, -// IMDGDistributedNames.Map_WorkflowStatus, -// WorkflowStatusDictionary.class), + DictionaryPresentRule.instance("workflowStatus", + CompanyNewRequest::getWorkflowStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue), + DictionaryPresentRule.instance("companySymbol", + CompanyNewRequest::getCompanySymbol, + IMDGDistributedNames.Map_CompanySymbolDictionary, + CompanySymbolDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue) + ); + }; + } + + @Bean("companyUpdateRequestValidator")//todo type of request + public Function companyUpdateRequestValidator(Map> imdgForValidation) { + return companyNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(companyNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_Company); + return new ValidatorImpl<>(context, + FieldRequiredRule.instance("id", CompanyNewRequest::getId, CompanyErrors.RequiredFieldEmpty), + + FieldRequiredRule.instance("shortName", CompanyNewRequest::getShortName, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("companySymbol", CompanyNewRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("companySymbolValue", CompanyNewRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("workflowStatus", CompanyNewRequest::getWorkflowStatus, CompanyErrors.RequiredFieldEmpty), + + DictionaryPresentRule.instance("workflowStatus", + CompanyNewRequest::getWorkflowStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue) +// DictionaryPresentRule.instance("companySymbol", +// CompanyNewRequest::getCompanySymbol, +// IMDGDistributedNames.Map_CompanySymbolDictionary, +// CompanySymbolDictionary.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.WrongFieldValue) ); }; } + @Bean("CompanyDeleteRequestValidator") + public Function companyDeleteRequestValidator(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_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound, + company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled) + ); + }; + } + } 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 9ce392c5d..20ce51e01 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 @@ -32,6 +32,10 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary, DocumentTypeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, DocumentTypeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class); + + return imdg; } 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 9a38c614d..69af48acd 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 @@ -9,6 +9,9 @@ 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.CompanySymbols; +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.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; @@ -16,116 +19,101 @@ 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.platform.messaging.service.QueueConsumer; -import ru.spcex.platform.enumeration.WorkflowStatus; +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.*; 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.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; -import java.util.Optional; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; import java.util.function.Function; @Service public class CompanyService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); + private final RequestHelper requestHelper; private final Imdg companyMap; + private final Imdg companySymnbolsMap; + private final Imdg relationMap; private final ImdgId idSequence; -// protected UserRoleVerification userRoleVerification; - protected IMessageResolver messageResolver; + protected UserRoleVerification userRoleVerification; + protected IMessageResolver messageResolver; + private ValidationHelper validationHelper; private Function companyNewRequestValidator; + private Function companyUpdateRequestValidator; + private Function companyDeleteRequestValidator; + + // Синхронизация обновлений + public final Object lockCompany = new Object(); // Company, CompanySymbol, @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, - IMessageResolver messageResolver, -// , UserRoleVerification userRoleVerification + IMessageResolver messageResolver, + UserRoleVerification userRoleVerification, + ValidationHelper validationHelper, @Qualifier("companyNewRequestValidator") - Function companyNewRequestValidator + Function companyNewRequestValidator, + @Qualifier("companyUpdateRequestValidator") + Function companyUpdateRequestValidator, + @Qualifier("CompanyDeleteRequestValidator") + Function companyDeleteRequestValidator ) { super(kafkaQueue, kafkaProducer); this.messageResolver = messageResolver; + this.requestHelper = new RequestHelper(log, messageResolver); this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.relationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + this.companySymnbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); -// this.userRoleVerification = userRoleVerification; + this.userRoleVerification = userRoleVerification; + this.validationHelper = validationHelper; this.companyNewRequestValidator = companyNewRequestValidator; + this.companyUpdateRequestValidator = companyUpdateRequestValidator; + this.companyDeleteRequestValidator = companyDeleteRequestValidator; } @Override public void afterPropertiesSet() { - RequestHelper requestHelper = new RequestHelper(log, messageResolver); callback(CommonDeleteRequest.class) - .setConsumer(this::deleteCompany) + .setConsumer(request -> requestHelper.requestFunction(this::deleteCompany, request)) .forDestination(Consts.DESTINATION_COMPANY_DELETE, callbacks::put); callback(CompanyNewRequest.class) - .setFunction( request -> requestHelper.requestFunction(this::createCompany, request)) + .setFunction(request -> requestHelper.requestFunction(this::createCompany, request)) .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); callback(CompanyNewRequest.class) - .setConsumer(this::updateCompany) + .setConsumer(request -> requestHelper.requestFunction(this::updateCompany, request)) .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); - //todo IV - сообщения на добавления документа расторжения договора - см. Документ расторжения договора. profileDocument): необходимо обновить запись в company согласно описанию с тэгом "При обработке расторжения". -// callback(CompanyNewRequest.class) -// .setConsumer(this::updateCompany) -// .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); init(); } -// -// interface RequestCommand { -// Long command(T arg) throws ClearingBaseException; -// } -// -// protected > Object requestFunction(RequestCommand command, T userRequest) { -// try { -// Long itemAffected = command.command(userRequest); -// log.trace("Item affected: {}", itemAffected); -// return null; -// } catch (ClearingBaseException expectedE) { -// log.trace("{} return expected exception: {}", command, expectedE.toString()); -// return new RequestInfoUpdate() -// .setId(userRequest.getId()) -// .setStatus(Status.Error) -// .setMessage(expectedE.getMessage()); -// } catch (Exception unexpectedE) { -// log.error("Error at {}: {} ", command, ExceptionUtils.getStackTrace(unexpectedE)); -// String message = messageResolver.resolve(new EnumMessage(CompanyErrors.GeneralError)); -// return new RequestInfoUpdate() -// .setId(userRequest.getId()) -// .setStatus(Status.Error) -// .setMessage(message); -// } -// } - protected void validateRole(BaseRequest req) throws ValidationException { - Long requestor = null; // todo требуется передавать это значение из frontendapi! req.getUserId(); -// if (!userRoleVerification.userHasRole(requestor, UserRole.Admin)) { -// -// }; - } - - void validate(CompanyNewRequest object) throws ValidationException { - IValidator validator = companyNewRequestValidator.apply(object); - Optional error = validator.tillFirstError(); - if (error.isPresent()) { - log.warn("CompanyNewRequest validation error: {}", error.get()); - throw new ValidationException(error.get()); -// String errorMsg = messageResolver.resolve(error.get()); -// return new RequestInfoUpdate() // todo reply message -// .setId(userRequest.getId()) -// .setStatus(Status.Error) -// .setMessage(errorMsg); + protected void validateRole(BaseRequest req) throws ValidationException { + Long requestor = req.getUserId(); + if (requestor != null && !userRoleVerification.userHasRole(requestor, UserRole.Admin)) { + log.trace("User {} has no role to allow this action", requestor); + throw new ValidationException(CompanyErrors.UserVerifyDenial); + } else { + log.trace("Request without userId"); } } - private Long createCompany(BaseRequest companyNewRequestBaseRequest) throws ValidationException { + + private synchronized RequestInfoUpdate createCompany(BaseRequest companyNewRequestBaseRequest) throws ValidationException { CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); { // Валидация, ValidationException validateRole(companyNewRequestBaseRequest); - validate(req); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyNewRequestBaseRequest, companyNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; } Company company = new Company(); company.setId(idSequence.nextId()); @@ -135,46 +123,223 @@ public class CompanyService extends QueueConsumer implements InitializingBean { company.setShortName(req.getShortName()); company.setFullName(req.getFullName()); - company.setTradingCode(req.getTradingCode()); - company.setClearingCode(req.getClearingCode()); - company.setRegistrationCode(req.getRegistrationCode()); + + if (req.getCompanySymbol() != null) { + CompanySymbols newSymbol = createCompanySymbol(company, req); + updateCompanyBySymbol(company, newSymbol); + log.debug("Created new companySymbols.id={} for company {}", newSymbol.getId(), company.getId()); + companySymnbolsMap.insert(newSymbol); + } company.setWorkflowStatus(WorkflowStatus.Active.getKey()); -// if (WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { -// -// } else if (WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { -// -// } companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); + createNewRelation(company); - return company.getId(); + return null; + } + + protected CompanySymbols createCompanySymbol(Company forCompany, CompanyNewRequest request) { + //todo see CompanySymbolService + CompanySymbols newSymbol = new CompanySymbols(); + newSymbol.setId(idSequence.nextId()); + newSymbol.setCompanyId(forCompany.getId()); + newSymbol.setCompanySymbol(request.getCompanySymbol()); + newSymbol.setCompanySymbolValue(request.getCompanySymbolValue()); + return newSymbol; } - private void updateCompany(BaseRequest companyNewRequestBaseRequest) { - //todo update -// CompanyUpdateRequest req = companyUpdateRequestBaseRequest.getRequestPayload(); -// log.debug("company-update request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); -// Company company = new Company(); -// company.setShortName(req.getShortName()); -// company.setFullName(req.getFullName()); -// company.setTradingCode(req.getTradingCode()); -// company.setClearingCode(req.getClearingCode()); -// company.setRegistrationCode(req.getRegistrationCode()); -// companyMap.insert(company); -// log.debug("company-update request processed, BaseRequest.id = {}, company.id={}", -// companyNewRequestBaseRequest.getId(), company.getId()); + private synchronized RequestInfoUpdate updateCompany(BaseRequest companyUpdateRequestBaseRequest) throws ValidationException { + CompanyNewRequest updateRequest = companyUpdateRequestBaseRequest.getRequestPayload(); + { // Валидация, ValidationException + validateRole(companyUpdateRequestBaseRequest); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyUpdateRequestBaseRequest, companyUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + Company company = companyMap.getSingleObjectByID(updateRequest.getId()); // todo use validationContext. + if (company == null) { + 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()); + } + + company.setUpdated(Instant.now()); + company.setShortName(updateRequest.getShortName()); + company.setFullName(updateRequest.getFullName()); + + if (updateRequest.getCompanySymbol() != null || updateRequest.getCompanySymbolValue() != null) { + log.trace("Request field CompanySymbol, CompanySymbolValue ignore for update company request."); + } + CompanySymbols companySymbol = companySymnbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); + if (companySymbol == null) { + log.warn("CompanySymbols not found for companyId={}", company.getId()); + } else { + log.trace("Found CompanySymbols.id={} for companyId={}", companySymbol.getId(), company.getId()); + updateCompanyBySymbol(company, companySymbol); + } + + +// String prevStatus = company.getWorkflowStatus(); +// if (updateRequest.getWorkflowStatus() != null) { +// company.setWorkflowStatus(updateRequest.getWorkflowStatus()); +// if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { +// onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); +// } else { +// log.trace("Status was not changed"); +// } +// } else { +// log.trace("Null new WorkflowStatus"); +// } + return null; + } + + protected void updateCompanyBySymbol(Company company, CompanySymbols companySymbol) { + assert company.getId().equals(companySymbol.getCompanyId()); + if (CompanySymbol.TRDC.equalsByKey(companySymbol.getCompanySymbol())) { + company.setTradingCode(companySymbol.getCompanySymbolValue()); + } else { + company.setTradingCode(null); + } + if (CompanySymbol.CLRC.equalsByKey(companySymbol.getCompanySymbol())) { + company.setClearingCode(companySymbol.getCompanySymbolValue()); + } else { + company.setClearingCode(null); + } + if (CompanySymbol.RGRC.equalsByKey(companySymbol.getCompanySymbol())) { + company.setRegistrationCode(companySymbol.getCompanySymbolValue()); + } else { + company.setRegistrationCode(null); + } } + protected static final Long SPVB_ID = 1L; // СПВБ - private void deleteCompany(BaseRequest userRequest) { - CommonDeleteRequest req = userRequest.getRequestPayload(); - log.debug("CommonDeleteRequest received id = {}", req.getId()); - Company company = companyMap.getSingleObjectByID(req.getId()); - companyMap.delete(company); + private void createNewRelation(Company company) { + Relation relation = new Relation(); + relation.setId(idSequence.nextId()); + relation.setCreated(Instant.now()); + relation.setUpdated(relation.getCreated()); + + relation.setConsumerId(company.getId()); + relation.setSupplierId(SPVB_ID); // 1 СПВБ + relation.setServiceStatus(WorkflowStatus.Active.getKey()); + relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR + relation.setServiceProduct(ServiceProduct.ZERO.getKey()); + log.debug("New Relation[{}] created.", relation.getId()); + relationMap.insert(relation); // todo use transaction! + } + + /** + * @param company + * @param oldStatus + * @param newStatus WorkflowStatus.Active - при возобналвении; WorkflowStatus.Blocked - при блокировки/расторжении + */ + private void onChangeWorkflowStatus(Company company, String oldStatus, String newStatus) { + //todo в ТЗ упоминается: ри изменении (relation/put): //из соответствующего параметра полученного метода, если значение отличается от сохраненного ране + log.debug("Company id={} status changed from {} to {}", + company.getId(), oldStatus, company.getWorkflowStatus()); + assert Objects.equals(newStatus, company.getWorkflowStatus()); + String query = String.format("consumerId=%s", company.getId()); + Collection relations = relationMap.getCollectionObjectsBySQL(query); + log.trace("Selected {} Relation by query: {}", relations.size(), query); + Instant now = Instant.now(); + for (Relation relation : relations) { + boolean modified = false; + if (WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { + if (!ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus())) { + relation.setServiceStatus(ServiceStatus.Reopened.getKey()); + modified = true; + } + } else if (WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { + if (!ServiceStatus.Closed.equalsByKey(relation.getServiceStatus())) { + relation.setServiceStatus(ServiceStatus.Closed.getKey()); + modified = true; + } + } + if (modified) { + relation.setUpdated(now); + log.debug("Relation id={} updated", relation.getId()); + relationMap.update(relation); + } + } + + } + + + /** + * Блокировка компании + * + * @param companyBlockRequestBaseRequest + * @return + */ + private synchronized RequestInfoUpdate deleteCompany(BaseRequest companyBlockRequestBaseRequest) throws ValidationException { + CommonDeleteRequest request = companyBlockRequestBaseRequest.getRequestPayload(); + log.debug("CommonDeleteRequest (block request) received id = {}", request.getId()); + { // Валидация, ValidationException + validateRole(companyBlockRequestBaseRequest); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyBlockRequestBaseRequest, companyDeleteRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + Company company = companyMap.getSingleObjectByID(request.getId()); + if (company == null) { + log.warn("Company {} not found", request.getId()); + return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyNotFound, request.getId()); + } +// if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { +// log.trace("Company {} not active: {}", company.getId(), company.getWorkflowStatus()); +// return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyDisabled, request.getId()); +// } + + company.setUpdated(Instant.now()); + + CompanySymbols companySymbol = companySymnbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); + if (companySymbol == null) { + log.warn("CompanySymbols not found for companyId={}", company.getId()); + } else { + log.trace("Found CompanySymbols.id={} for companyId={}", companySymbol.getId(), company.getId()); + updateCompanyBySymbol(company, companySymbol); + } + + String prevStatus = company.getWorkflowStatus(); + company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); + onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); + log.debug("Update company.id={}", company.getId()); + companyMap.update(company); + + // todo kafka send !!! Account. + return null; + +// Company company = companyMap.getSingleObjectByID(req.getId()); +// companyMap.delete(company); + } + + + /** + * IV - сообщения на добавления документа расторжения договора + * + * @param companyId + */ + public synchronized void onRastorjeniye(Long companyId) { + Company company = companyMap.getSingleObjectByID(companyId); + if (company == null) { + log.warn("Company {} not found", companyId); + return; + } + + if (!WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { + log.debug("Update company.id={}", company.getId()); + company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); + company.setUpdated(Instant.now()); + companyMap.update(company); + } else { + log.trace("Company {} already has blocked.", companyId); + } } } 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 5cbb5d6da..1b810e700 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 @@ -6,6 +6,7 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ClearingBaseException; import ru.spcex.platform.utils.log.ExceptionUtils; @@ -42,9 +43,10 @@ public class RequestHelper { */ public > RequestInfoUpdate requestFunction(RequestCommand command, T userRequest) { try { - Long itemAffected = command.command(userRequest); - log.trace("Item affected: {}", itemAffected); - return null; + log.debug("{} request received, BaseRequest.id = {}", userRequest.getClass().getSimpleName(), userRequest.getId()); + RequestInfoUpdate reply = command.command(userRequest); + log.trace("Reply on request {}: {}" , userRequest.getId(), reply); + return reply; } catch (ClearingBaseException expectedE) { log.trace("{} return expected exception: {}", command, expectedE.toString()); String message = expectedE.getEnumMsg() == null @@ -64,7 +66,21 @@ public class RequestHelper { } } + public RequestInfoUpdate makeErrorResponse(BaseRequest request, EnumMessage msg) { + String errorMsg = msg == null? "" : messageResolver.resolve(msg); + return new RequestInfoUpdate() + .setId(request.getId()) + .setStatus(Status.Error) + .setMessage(errorMsg); + } + + + public RequestInfoUpdate makeErrorResponse(BaseRequest request, IEnumId error, Object ... args) { + //todo должны уточнить интерфейс IEnumId в CompanyErrors, вечером проверить код. + return makeErrorResponse(request, new EnumMessage(error, args)); + } + public interface RequestCommand { - Long command(T arg) throws ClearingBaseException; + RequestInfoUpdate command(T arg) throws ClearingBaseException; } } diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java new file mode 100644 index 000000000..cec73efc2 --- /dev/null +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java @@ -0,0 +1,21 @@ +package ru.spcex.clearing.company.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; + +@Configuration +public class BeanConfiguration { + @Bean + public IMessageResolver messageResolver() { + return new SimpleMessageResolver(); + } + + @Bean + UserRoleVerification userRoleVerification(ImdgProvider imdg) { + return new UserRoleVerification(imdg); + } +} 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 b8cd3e7e2..84ce45c8a 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 @@ -14,33 +14,47 @@ 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.classes.statics.data.generated.ClearingMemberCategory; +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.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; 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.platform.enumeration.CompanySymbol; +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 java.util.Map; + import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.company.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanyService.class, + CompanyValidationConfig.class, + ValidationConfig.class, + KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + HazelcastServiceTestConfiguration.class, + BeanConfiguration.class}) class CompanyServiceTest { 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; - private static final Long ID = 0L; @Autowired CompanyService companyService; @@ -48,6 +62,7 @@ class CompanyServiceTest { @Qualifier("hazelcastServiceTest") private HazelcastService hazelcastServiceTest; private Imdg companyImdg; + private Imdg workflowStatusDictionaryImdg; @Captor private ArgumentCaptor producerRecord; @@ -58,6 +73,28 @@ class CompanyServiceTest { private void init() { hazelcastServiceTest.waitAvailable(); companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.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); + } } /** @@ -69,8 +106,10 @@ class CompanyServiceTest { @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(); @@ -84,6 +123,42 @@ class CompanyServiceTest { waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); Company resultDeleting = companyImdg.getSingleObjectByID(ID); - Assertions.assertNull(resultDeleting); + Assertions.assertEquals(WorkflowStatus.Blocked.getKey(), resultDeleting.getWorkflowStatus()); + //Assertions.assertNull(resultDeleting); + } + + + /** + * {@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) companyService.getConsumer(), DESTINATION_COMPANY_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + Company resultNew = companyImdg.getSingleObjectByFieldValues(Map.of("ShortName", "ClrIPO")); + Assertions.assertNotNull(resultNew); + Assertions.assertEquals("ClrIPO", resultNew.getShortName()); + Assertions.assertEquals(WorkflowStatus.Active.getKey(), resultNew.getWorkflowStatus()); } } \ No newline at end of file From d07674e2c6997362f5c77f60488d261de3443289 Mon Sep 17 00:00:00 2001 From: akulikov Date: Tue, 4 Apr 2023 16:21:13 +0300 Subject: [PATCH 26/90] ContactNewRequest --- .../platform/messaging/domain/Consts.java | 1 + .../domain/cud/company/ContactNewRequest.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactNewRequest.java 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 7e768cc99..5ee689fce 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 @@ -35,6 +35,7 @@ public interface Consts { String DESTINATION_COMPANY_BLOCK = "company-block"; String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update"; String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update"; + String DESTINATION_CONTACT_NEW = "contact-new"; String DESTINATION_CONTACT_UPDATE = "contact-update"; String DESTINATION_CLEARING_MEMBER_CATEGORY_NEW = "clearing-member-category-new"; String DESTINATION_CLEARING_MEMBER_CATEGORY_UPDATE = "clearing-member-category-update"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactNewRequest.java new file mode 100644 index 000000000..8df5eea1c --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactNewRequest.java @@ -0,0 +1,36 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ContactNewRequest { + @JsonProperty + private Long companyId; + @JsonProperty + private String contactType; + @JsonProperty + private String contactValue; + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public String getContactType() { + return contactType; + } + + public void setContactType(String contactType) { + this.contactType = contactType; + } + + public String getContactValue() { + return contactValue; + } + + public void setContactValue(String contactValue) { + this.contactValue = contactValue; + } +} From e2ce49e3e52db4892e5118181a935e6f728cf199 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Tue, 4 Apr 2023 18:13:52 +0300 Subject: [PATCH 27/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20FixedIncomeSecu?= =?UTF-8?q?rityService.java,=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8,=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/securities-service/pom.xml | 4 + .../securities/component/ListingBuilder.java | 36 ++ .../securities/config/KafkaConfig.java | 3 + .../securities/config/ValidationConfig.java | 17 + .../service/cud/EquitySecurityService.java | 93 +++-- .../cud/FixedIncomeSecurityService.java | 189 ++++++++++ .../cud/MoneyMarketSecurityService.java | 30 +- .../validation/ValidationProvider.java | 58 +++- .../rule/EquityNewValidationRule.java | 2 +- .../rule/FixedIncomeNewValidationRule.java | 31 ++ .../rule/IsValidInstrumentTypeById.java | 33 ++ ... => IsValidInstrumentTypeFromRequest.java} | 4 +- .../validation/rule/MmsNewValidationRule.java | 6 +- ...BySecuritySymbolAndWorkflowStatusActv.java | 2 +- .../HazelcastInstanceTestConfiguration.java | 16 - ...Configuration.java => ImdgTestConfig.java} | 46 +-- .../securities/config/KafkaTestConfig.java | 42 +++ .../service/AbstractServiceTest.java | 74 ++++ .../service/EquitySecurityServiceTest.java | 210 ++++++++++++ .../FixedIncomeSecurityServiceTest.java | 227 ++++++++++++ .../service/MoneyMarketSecurityFactory.java | 24 +- .../MoneyMarketSecurityServiceDisabled.java | 324 ------------------ .../MoneyMarketSecurityServiceTest.java | 179 ++++++++++ .../clearing/securities/utils/TestUtils.java | 123 +++++++ 24 files changed, 1349 insertions(+), 424 deletions(-) create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/FixedIncomeNewValidationRule.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java rename clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/{IsValidInstrumentType.java => IsValidInstrumentTypeFromRequest.java} (83%) delete mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastInstanceTestConfiguration.java rename clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/{HazelcastServiceTestConfiguration.java => ImdgTestConfig.java} (62%) create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/KafkaTestConfig.java create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java delete mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceDisabled.java create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/TestUtils.java diff --git a/clearing-parent/securities-service/pom.xml b/clearing-parent/securities-service/pom.xml index 6d3e62da1..742105bf4 100644 --- a/clearing-parent/securities-service/pom.xml +++ b/clearing-parent/securities-service/pom.xml @@ -24,6 +24,10 @@ ru.spcex.platform platform-enum + + ru.spcex.clearing + clearing-utils + ru.spcex.platform platform-imdg-api-hazelcast-impl diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java index 79d6f32d3..d8cec1b88 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java @@ -1,9 +1,11 @@ package ru.spcex.clearing.securities.component; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; +import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; import ru.spcex.platform.enumeration.Market; import ru.spcex.platform.enumeration.Status; @@ -23,6 +25,17 @@ public class ListingBuilder { listing.setWorkflowStatus(Status.Active.getKey()); return listing; } + public Listing byUpdateMms(MoneyMarketSecurity mms, Listing listing) { + listing.setSecurityId(mms.getId()); + listing.setSymbolCode(mms.getSecuritySymbol()); + listing.setSymbolName(mms.getFullName()); + listing.setTradingCurrency(mms.getNominalCurrency()); + listing.setWorkflowStatus(mms.getWorkflowStatus()); + listing.setLotSize(mms.getLotSize()); + listing.setUpdated(mms.getUpdated()); + return listing; + } + public Listing byNewEquity(EquitySecurity equitySecurity, EquitySecurityNewRequest request) { Listing listing = new Listing(); listing.setCreated(equitySecurity.getCreated()); @@ -35,4 +48,27 @@ public class ListingBuilder { listing.setWorkflowStatus(Status.Active.getKey()); return listing; } + + public Listing byUpdateEquity(EquitySecurity equitySecurity, Listing listing) { + listing.setSecurityId(equitySecurity.getId()); + listing.setSymbolCode(equitySecurity.getSecuritySymbol()); + listing.setSymbolName(equitySecurity.getFullName()); + listing.setWorkflowStatus(equitySecurity.getWorkflowStatus()); + listing.setLotSize(equitySecurity.getLotSize()); + listing.setUpdated(equitySecurity.getUpdated()); + return listing; + } + + public Listing byNewFixedIncome(FixedIncomeSecurity instant, FixedIncomeSecurityNewRequest request) { + Listing listing = new Listing(); + listing.setCreated(instant.getCreated()); + listing.setSecurityId(instant.getId()); + listing.setLotSize(BigDecimal.valueOf(request.getLotSize())); + listing.setMarket(Market.mkrs.getKey()); + listing.setSymbolCode(instant.getSecuritySymbol()); + listing.setSymbolName(instant.getFullName()); + listing.setTradingCurrency(instant.getNominalCurrency()); + listing.setWorkflowStatus(Status.Active.getKey()); + return listing; + } } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/KafkaConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/KafkaConfig.java index 1669d0e82..34826f19b 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/KafkaConfig.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/KafkaConfig.java @@ -3,8 +3,10 @@ package ru.spcex.clearing.securities.config; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.producer.Producer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory; import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory; import ru.spcex.clearing.securities.config.element.SecuritiesServiceSettings; @@ -13,6 +15,7 @@ import ru.spcex.clearing.securities.config.element.SecuritiesServiceSettings; public class KafkaConfig { @Autowired + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Bean public Consumer createConsumer(SecuritiesServiceSettings settings) { return KafkaConsumerFactory.consumer(settings.getKafkaConsumer()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java new file mode 100644 index 000000000..253f2395c --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java @@ -0,0 +1,17 @@ +package ru.spcex.clearing.securities.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.utils.enumeration.IMessageResolver; + + +@Configuration +public class ValidationConfig { + + @Bean("validationHelper") + public ValidationHelper validationHelper(IMessageResolver messageResolver) { + return new ValidationHelper(messageResolver); + } + +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java index 81af0e134..4744748b9 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java @@ -17,19 +17,17 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurit import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; 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.securities.component.ListingBuilder; import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; -import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IMessageResolver; import java.math.BigDecimal; import java.time.Instant; -import java.util.Optional; +import java.util.Map; @Service public class EquitySecurityService extends QueueConsumer implements InitializingBean { @@ -39,53 +37,46 @@ public class EquitySecurityService extends QueueConsumer implements Initializing private final ImdgProvider imdgProvider; private final ImdgId idGenerator; private final ValidationProvider validation; - private final IMessageResolver messageResolver; + private final ValidationHelper validationHelper; private final ListingBuilder listingBuilder = new ListingBuilder(); @Autowired public EquitySecurityService(Consumer kafkaQueue, - Producer kafkaProducer, - ImdgProvider imdgProvider, - ValidationProvider validation, - IMessageResolver messageResolver) { + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationProvider validation, + ValidationHelper validationHelper) { super(kafkaQueue, kafkaProducer); this.validation = validation; this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); this.imdgProvider = imdgProvider; this.idGenerator = imdgProvider.getImdgIdGenerator(); - this.messageResolver = messageResolver; + this.validationHelper = validationHelper; } @Override public void afterPropertiesSet() { callback(EquitySecurityNewRequest.class) .setFunction(this::newEquity) - .forDestination(Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW, callbacks::put); + .forDestination(Consts.DESTINATION_EQUITY_SECURITY_NEW, callbacks::put); callback(EquitySecurityUpdateRequest.class) .setFunction(this::updateEquity) - .forDestination(Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE, callbacks::put); + .forDestination(Consts.DESTINATION_EQUITY_SECURITY_UPDATE, callbacks::put); callback(CommonDeleteRequest.class) .setFunction(this::deleteEquity) - .forDestination(Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE, callbacks::put); + .forDestination(Consts.DESTINATION_EQUITY_SECURITY_DELETE, callbacks::put); imdgProvider.waitAvailable(); init(); } - private RequestInfoUpdate newEquity(BaseRequest userRequest){ + private RequestInfoUpdate newEquity(BaseRequest userRequest) { ImdgTransaction transaction = imdgProvider.newTransaction(); EquitySecurityNewRequest req = userRequest.getRequestPayload(); - Optional validationError = validation.equityNewValidator() - .apply(req) - .tillFirstError(); - if (validationError.isPresent()) { - String errorMsg = messageResolver.resolve(validationError.get()); - log.error("cannot process EquitySecurityNewRequest id={}: {}", userRequest.getId(), errorMsg); - return new RequestInfoUpdate() - .setId(userRequest.getId()) - .setStatus(Status.Error) - .setMessage(errorMsg); - } + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityNewValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + log.debug("EquitySecurityNewRequest received"); EquitySecurity equity = new EquitySecurity(); equity.setId(idGenerator.nextId()); @@ -96,6 +87,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing equity.setShareType(req.getShareType()); equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); equity.setIssuerId(req.getIssuerId()); + equity.setShortNameEng(req.getShortNameEng()); equity.setFullNameEng(req.getFullNameEng()); equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); equity.setInstrumentType(req.getInstrumentType()); @@ -121,11 +113,60 @@ public class EquitySecurityService extends QueueConsumer implements Initializing return null; // default success } - private RequestInfoUpdate updateEquity(BaseRequest userRequest){ + private RequestInfoUpdate updateEquity(BaseRequest userRequest) { + EquitySecurityUpdateRequest req = userRequest.getRequestPayload(); + log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityUpdateValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + EquitySecurity equity = equitySecurityImdg.getSingleObjectByID(req.getId()); + Instant updateTime = Instant.now(); + equity.setUpdated(updateTime); + equity.setSecuritySymbol(req.getSecuritySymbol()); + equity.setShortName(req.getShortName()); + equity.setFullName(req.getFullName()); + equity.setIsin(req.getIsin()); + equity.setShareType(req.getShareType()); + equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setIssuerId(req.getIssuerId()); + equity.setShortNameEng(req.getShortNameEng()); + equity.setFullNameEng(req.getFullNameEng()); + equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + equity.setInstrumentType(req.getInstrumentType()); + + equitySecurityImdg.update(equity); + Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); + if (listing == null) { + log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); + return null; + } + listing = listingBuilder.byUpdateEquity(equity, listing); + listingImdg.update(listing); return null; } private RequestInfoUpdate deleteEquity(BaseRequest userRequest) { + CommonDeleteRequest req = userRequest.getRequestPayload(); + log.debug("CommonDeleteRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityDeleteValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + Instant updateTime = Instant.now(); + EquitySecurity equity = equitySecurityImdg.getSingleObjectByID(req.getId()); + equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + equity.setUpdated(updateTime); + equitySecurityImdg.update(equity); + + Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); + if (listing == null) { + log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); + return null; + } + listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + listing.setUpdated(updateTime); + listingImdg.update(listing); return null; } } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java new file mode 100644 index 000000000..bb5b8af08 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java @@ -0,0 +1,189 @@ +package ru.spcex.clearing.securities.service.cud; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; +import ru.clearing.classes.statics.data.misc.Listing; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.securities.component.ListingBuilder; +import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.ImdgTransaction; + +import java.math.BigDecimal; +import java.time.Instant; +import java.util.Map; + +@Service +public class FixedIncomeSecurityService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg fixedIncomeSecurityImdg; + private final Imdg

listingImdg; + private final ImdgProvider imdgProvider; + private final ImdgId idGenerator; + private final ValidationProvider validation; + private final ValidationHelper validationHelper; + private final ListingBuilder listingBuilder = new ListingBuilder(); + + @Autowired + public FixedIncomeSecurityService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationProvider validation, + ValidationHelper validationHelper) { + super(kafkaQueue, kafkaProducer); + this.validation = validation; + this.fixedIncomeSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class); + this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.validationHelper = validationHelper; + } + + @Override + public void afterPropertiesSet() { + callback(FixedIncomeSecurityNewRequest.class) + .setFunction(this::newFixedIncome) + .forDestination(Consts.DESTINATION_FIXED_INCOME_SECURITY_NEW, callbacks::put); + callback(FixedIncomeSecurityUpdateRequest.class) + .setFunction(this::updateFixedIncome) + .forDestination(Consts.DESTINATION_FIXED_INCOME_SECURITY_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::deleteFixedIncome) + .forDestination(Consts.DESTINATION_FIXED_INCOME_SECURITY_DELETE, callbacks::put); + imdgProvider.waitAvailable(); + init(); + } + + private RequestInfoUpdate newFixedIncome(BaseRequest userRequest) { + ImdgTransaction transaction = imdgProvider.newTransaction(); + FixedIncomeSecurityNewRequest req = userRequest.getRequestPayload(); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeNewValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + log.debug("EquitySecurityNewRequest received"); + FixedIncomeSecurity fixedIncome = new FixedIncomeSecurity(); + fixedIncome.setId(idGenerator.nextId()); + fixedIncome.setSecuritySymbol(req.getSecuritySymbol()); + fixedIncome.setShortName(req.getShortName()); + fixedIncome.setFullName(req.getFullName()); + fixedIncome.setIsin(req.getIsin()); + fixedIncome.setBondType(req.getBondType()); + fixedIncome.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + fixedIncome.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); + fixedIncome.setNominalCurrency(req.getNominalCurrency()); + fixedIncome.setMaturityDate(req.getMaturityDate()); + fixedIncome.setCoupon(req.getCoupon() != null ? BigDecimal.valueOf(req.getCoupon()) : null); + fixedIncome.setCouponFrequency(req.getCouponFrequency()); + fixedIncome.setIssuerId(req.getIssuerId()); + fixedIncome.setShortNameEng(req.getShortNameEng()); + fixedIncome.setFullNameEng(req.getFullNameEng()); + fixedIncome.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + fixedIncome.setInstrumentType(req.getInstrumentType()); + fixedIncome.setSecurityId(fixedIncome.getId()); + fixedIncome.setCreated(Instant.now()); + try { + transaction.beginTransaction(); + Imdg fixedIncomeImdg = transaction.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class); + Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + //одним скопом выполняем реквест + fixedIncomeImdg.insert(fixedIncome); + Listing listing = listingBuilder.byNewFixedIncome(fixedIncome, req); + listingMap.insert(listing); + //и сохраняем обновленный +// reqInfoMap.insert(reqInfo); + transaction.commitTransaction(); + } catch (Throwable e) { + transaction.rollbackTransaction(); +// RequestInfo.update(reqInfo, Status.Error, ExceptionUtils.getStackTrace(e)); +// requestInfoImdg.insert(reqInfo); + } + log.debug("successfully processed, request id {}, new object id {}", userRequest.getId(), fixedIncome.getId()); + return null; // default success + } + + private RequestInfoUpdate updateFixedIncome(BaseRequest userRequest) { + FixedIncomeSecurityUpdateRequest req = userRequest.getRequestPayload(); + log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeUpdateValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + FixedIncomeSecurity fixedIncome = fixedIncomeSecurityImdg.getSingleObjectByID(req.getId()); + Instant updateTime = Instant.now(); + fixedIncome.setUpdated(updateTime); + fixedIncome.setSecuritySymbol(req.getSecuritySymbol()); + fixedIncome.setShortName(req.getShortName()); + fixedIncome.setFullName(req.getFullName()); + fixedIncome.setIsin(req.getIsin()); + fixedIncome.setBondType(req.getBondType()); + fixedIncome.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + fixedIncome.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); + fixedIncome.setNominalCurrency(req.getNominalCurrency()); + fixedIncome.setMaturityDate(req.getMaturityDate()); + fixedIncome.setCoupon(req.getCoupon() != null ? BigDecimal.valueOf(req.getCoupon()) : null); + fixedIncome.setCouponFrequency(req.getCouponFrequency()); + fixedIncome.setIssuerId(req.getIssuerId()); + fixedIncome.setShortNameEng(req.getShortNameEng()); + fixedIncome.setFullNameEng(req.getFullNameEng()); + fixedIncome.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + fixedIncome.setInstrumentType(req.getInstrumentType()); + fixedIncome.setSecurityId(fixedIncome.getId()); + + fixedIncomeSecurityImdg.update(fixedIncome); + Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncome.getId())); + if (listing == null) { + log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId()); + return null; + } + listing.setSecurityId(fixedIncome.getId()); + listing.setSymbolCode(fixedIncome.getSecuritySymbol()); + listing.setSymbolName(fixedIncome.getFullName()); + listing.setTradingCurrency(fixedIncome.getNominalCurrency()); + listing.setWorkflowStatus(fixedIncome.getWorkflowStatus()); + listing.setLotSize(fixedIncome.getLotSize()); + listing.setUpdated(updateTime); + listingImdg.update(listing); + return null; + } + + private RequestInfoUpdate deleteFixedIncome(BaseRequest userRequest) { + CommonDeleteRequest req = userRequest.getRequestPayload(); + log.debug("CommonDeleteRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityDeleteValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + Instant updateTime = Instant.now(); + FixedIncomeSecurity equity = fixedIncomeSecurityImdg.getSingleObjectByID(req.getId()); + equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + equity.setUpdated(updateTime); + fixedIncomeSecurityImdg.update(equity); + + Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); + if (listing == null) { + log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); + return null; + } + listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + listing.setUpdated(updateTime); + listingImdg.update(listing); + return null; + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java index 51190d495..493124d92 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java @@ -21,6 +21,7 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -43,6 +44,7 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial private final ImdgProvider imdgProvider; private final ImdgId idGenerator; private final ValidationProvider validation; + private final ValidationHelper validationHelper; private final IMessageResolver messageResolver; private final ListingBuilder listingBuilder = new ListingBuilder(); @@ -51,8 +53,10 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial Producer kafkaProducer, ImdgProvider imdgProvider, ValidationProvider validation, + ValidationHelper validationHelper, IMessageResolver messageResolver) { super(kafkaQueue, kafkaProducer); + this.validationHelper = validationHelper; this.validation = validation; this.moneyMarketSecurityMap = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class); this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); @@ -94,17 +98,10 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial private RequestInfoUpdate newMoneyMarket(BaseRequest userRequest) { ImdgTransaction transaction = imdgProvider.newTransaction(); MoneyMarketSecurityNewRequest req = userRequest.getRequestPayload(); - Optional validationError = validation.mmsNewValidator() - .apply(req) - .tillFirstError(); - if (validationError.isPresent()) { - String errorMsg = messageResolver.resolve(validationError.get()); - log.error("cannot process MoneyMarketSecurityNewRequest id={}: {}", userRequest.getId(), errorMsg); - return new RequestInfoUpdate() - .setId(userRequest.getId()) - .setStatus(Status.Error) - .setMessage(errorMsg); - } + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.mmsNewValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + log.debug("MoneyMarketSecurityNewRequest received"); MoneyMarketSecurity mms = new MoneyMarketSecurity(); mms.setId(idGenerator.nextId()); @@ -122,7 +119,7 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setTermType(req.getTermType()); mms.setIsin(req.getIsin()); mms.setSecurityId(mms.getId()); - mms.setDescription(mms.getDescription()); + mms.setDescription(req.getDescription()); mms.setCreated(Instant.now()); mms.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); try { @@ -176,7 +173,6 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setIsin(req.getIsin()); mms.setSecurityId(mms.getId()); mms.setDescription(mms.getDescription()); - mms.setCreated(Instant.now()); moneyMarketSecurityMap.update(mms); Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); @@ -184,8 +180,7 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId()); return null; } - listing.setLotSize(mms.getLotSize()); - listing.setUpdated(updateTime); + listing = listingBuilder.byUpdateMms(mms, listing); listingImdg.update(listing); return null; } @@ -203,9 +198,10 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial .setStatus(Status.Error) .setMessage(errorMsg); } + Instant updateTime = Instant.now(); MoneyMarketSecurity mms = validator.getStored(Stored.PresentById); mms.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); - mms.setUpdated(Instant.now()); + mms.setUpdated(updateTime); moneyMarketSecurityMap.update(mms); Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); if (listing == null) { @@ -213,7 +209,7 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial return null; } listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); - listing.setUpdated(Instant.now()); + listing.setUpdated(updateTime); listingImdg.update(listing); return null; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index 8f09e27c5..40371d3a4 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -3,10 +3,7 @@ package ru.spcex.clearing.securities.validation; import org.springframework.stereotype.Component; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.*; import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.clearing.securities.validation.rule.*; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -23,11 +20,13 @@ import java.util.function.Function; public class ValidationProvider { private final Imdg mmsMap; private final Imdg equityMap; + private final Imdg fixedIncomeMap; public ValidationProvider(ImdgProvider imdgProvider) { this.mmsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, SpcexObjectBase.class); this.equityMap = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, SpcexObjectBase.class); + this.fixedIncomeMap = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, SpcexObjectBase.class); } public Function mmsNewValidator() { @@ -38,7 +37,7 @@ public class ValidationProvider { return new ValidatorImpl<>(context, EndDtAfterStartDt.instance(MoneyMarketSecurityNewRequest.class), new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentAlreadyExists, MoneyMarketSecurityNewRequest.class), - new IsValidInstrumentType(SecuritiesError.RequiredFieldIsEmpty, "RATE"), + new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "RATE"), MmsNewValidationRule.RequiredFieldIsNotEmpty ); }; @@ -51,8 +50,8 @@ public class ValidationProvider { context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); return new ValidatorImpl<>(context, EndDtAfterStartDt.instance(MoneyMarketSecurityUpdateRequest.class), - new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "RATE"), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), new WorkflowStatusActv() ); }; @@ -64,8 +63,8 @@ public class ValidationProvider { context.setValidatedObject(mmsRequest); context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); return new ValidatorImpl<>(context, - new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "RATE"), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), new WorkflowStatusActv() ); }; @@ -78,7 +77,7 @@ public class ValidationProvider { context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); return new ValidatorImpl<>(context, new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentAlreadyExists, EquitySecurityNewRequest.class), - new IsValidInstrumentType(SecuritiesError.RequiredFieldIsEmpty, "EQTY"), + new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "EQTY"), EquityNewValidationRule.RequiredFieldIsNotEmpty ); }; @@ -90,8 +89,8 @@ public class ValidationProvider { context.setValidatedObject(equityRequest); context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); return new ValidatorImpl<>(context, - new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "EQTY"), new PresentById(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentNotFound, true), + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "EQTY"), new WorkflowStatusActv() ); }; @@ -103,8 +102,47 @@ public class ValidationProvider { context.setValidatedObject(equityRequest); context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); return new ValidatorImpl<>(context, - new IsValidInstrumentType(SecuritiesError.InstrumentNotFound, "EQTY"), new PresentById(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentNotFound, true), + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "EQTY"), + new WorkflowStatusActv() + ); + }; + } + + public Function fixedIncomeNewValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, equityMap); + return new ValidatorImpl<>(context, + new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentAlreadyExists, FixedIncomeSecurityNewRequest.class), + new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "BOND"), + FixedIncomeNewValidationRule.RequiredFieldIsNotEmpty + ); + }; + } + + public Function fixedIncomeUpdateValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, equityMap); + return new ValidatorImpl<>(context, + new PresentById(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentNotFound, true), + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "BOND"), + new WorkflowStatusActv() + ); + }; + } + + public Function fixedIncomeDeleteValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, equityMap); + return new ValidatorImpl<>(context, + new PresentById(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentNotFound, true), + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "BOND"), new WorkflowStatusActv() ); }; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java index 31d2cb36a..6e61fb0c8 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java @@ -14,7 +14,7 @@ public enum EquityNewValidationRule implements IValidationRule validate(ImdgValidationContext context) { EquitySecurityNewRequest action = context.getValidatedObject(); - if (StringUtils.hasText(action.getShortName())){ + if (!StringUtils.hasText(action.getShortName())){ return of(SecuritiesError.RequiredFieldIsEmpty, "shortName"); } if (action.getLotSize() == null) { diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/FixedIncomeNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/FixedIncomeNewValidationRule.java new file mode 100644 index 000000000..fd08634c8 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/FixedIncomeNewValidationRule.java @@ -0,0 +1,31 @@ +package ru.spcex.clearing.securities.validation.rule; + +import org.springframework.util.StringUtils; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; +import ru.spcex.clearing.securities.errors.SecuritiesError; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; + +public enum FixedIncomeNewValidationRule implements IValidationRule> { + RequiredFieldIsNotEmpty() { + @Override + public Optional validate(ImdgValidationContext context) { + FixedIncomeSecurityNewRequest action = context.getValidatedObject(); + if (!StringUtils.hasText(action.getShortName())){ + return of(SecuritiesError.RequiredFieldIsEmpty, "shortName"); + } + if (action.getLotSize() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "lotSize"); + } + return empty(); + } + }; + + @Override + public String ruleName() { + return "MmsNewValidationRule." + name(); + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java new file mode 100644 index 000000000..21b30f3af --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java @@ -0,0 +1,33 @@ +package ru.spcex.clearing.securities.validation.rule; + +import ru.spcex.clearing.securities.errors.SecuritiesError; +import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.imdg.validation.Stored; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; + +public class IsValidInstrumentTypeById implements IValidationRule> { + private final IEnumId errorEnum; + private final String predictableInstrumentType; + + public IsValidInstrumentTypeById(IEnumId errorEnum, String predictableInstrumentType) { + this.errorEnum = errorEnum; + this.predictableInstrumentType = predictableInstrumentType; + } + + @Override + public Optional validate(ImdgValidationContext context) { + WithInstrumentType action = context.getStoredObject(Stored.PresentById); + if (action.getInstrumentType() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty); + } else if (!predictableInstrumentType.equalsIgnoreCase(action.getInstrumentType())){ + return of(errorEnum); + }else { + return empty(); + } + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentType.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java similarity index 83% rename from clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentType.java rename to clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java index 04c8878d7..68b8bb857 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentType.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java @@ -9,11 +9,11 @@ import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; -public class IsValidInstrumentType implements IValidationRule> { +public class IsValidInstrumentTypeFromRequest implements IValidationRule> { private final IEnumId errorEnum; private final String predictableInstrumentType; - public IsValidInstrumentType(IEnumId errorEnum, String predictableInstrumentType) { + public IsValidInstrumentTypeFromRequest(IEnumId errorEnum, String predictableInstrumentType) { this.errorEnum = errorEnum; this.predictableInstrumentType = predictableInstrumentType; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java index de4eaff95..5c19b309c 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/MmsNewValidationRule.java @@ -14,7 +14,7 @@ public enum MmsNewValidationRule implements IValidationRule validate(ImdgValidationContext context) { MoneyMarketSecurityNewRequest action = context.getValidatedObject(); - if (StringUtils.hasText(action.getShortName())){ + if (!StringUtils.hasText(action.getShortName())){ return of(SecuritiesError.RequiredFieldIsEmpty, "shortName"); } if (action.getLotSize() == null) { @@ -23,10 +23,10 @@ public enum MmsNewValidationRule implements IValidationRule validate(ImdgValidationContext context) { WithSecuritySymbol action = context.getValidatedObject(); Imdg imdg = context.obtainMap(mapName, clazz); - if(StringUtils.hasText(action.getSecuritySymbol())) { + if(!StringUtils.hasText(action.getSecuritySymbol())) { return of(SecuritiesError.RequiredFieldIsEmpty, "securitySymbole"); } T object = imdg.getSingleObjectByFieldValues(Map.of( diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastInstanceTestConfiguration.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastInstanceTestConfiguration.java deleted file mode 100644 index c8294909c..000000000 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastInstanceTestConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package ru.spcex.clearing.securities.config; - -import com.hazelcast.client.HazelcastClient; -import com.hazelcast.core.HazelcastInstance; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class HazelcastInstanceTestConfiguration { - - @Bean(name = "hazelcastInstance") - public HazelcastInstance hazelcastInstance() { - return HazelcastClient.newHazelcastClient(); - } - -} \ No newline at end of file diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastServiceTestConfiguration.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java similarity index 62% rename from clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastServiceTestConfiguration.java rename to clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java index 3af3f0514..95f01963c 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java @@ -3,10 +3,12 @@ package ru.spcex.clearing.securities.config; import com.hazelcast.config.*; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper; @@ -15,10 +17,11 @@ import java.util.List; import java.util.Random; @Configuration -public class HazelcastServiceTestConfiguration { +public class ImdgTestConfig { + private HazelcastInstance hazelcastInstance; - private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) { + private static ThreadPoolTaskExecutor createThreadPoolTestTaskExecutor(int maxPoolSz, boolean waitForCompletion) { ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor(); if (maxPoolSz > 2) { pool.setKeepAliveSeconds(60); @@ -29,34 +32,34 @@ public class HazelcastServiceTestConfiguration { return pool; } + @Bean(name = "taskExecutorHazelcastTestClientInitializer") + public ThreadPoolTaskExecutor taskExecutorHazelcastTestClientInitializer() { + return createThreadPoolTestTaskExecutor(1, true); + } + + @Bean(name = "taskExecutorTestIdGeneratorAwaiter") + public ThreadPoolTaskExecutor taskExecutorTestIdGeneratorAwaiter() { + return createThreadPoolTestTaskExecutor(1, false); + } + + @Autowired @Bean(name = "hazelcastServiceTest") - public HazelcastService hazelcastService(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, HazelcastClientParams params) { + public ImdgProvider imdgTestProvider( + @Qualifier("taskExecutorHazelcastTestClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, + @Qualifier("taskExecutorTestIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, + HazelcastClientParams params) { Config cfg = new Config(); cfg.setInstanceName("localhost"); NetworkConfig networkConfig = new NetworkConfig(); JoinConfig joinConfig = new JoinConfig(); joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false)); - joinConfig.setTcpIpConfig(new TcpIpConfig(). - setEnabled(true).setMembers(List.of("127.0.0.1"))); + joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1"))); networkConfig.setJoin(joinConfig); - cfg.setNetworkConfig(networkConfig); - hazelcastInstance = Hazelcast.newHazelcastInstance(cfg); - + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); - return new HazelcastService(taskExecutorHazelcastClientInitializer, - taskExecutorIdGeneratorAwaiter, params); - } - - @Bean(name = "taskExecutorHazelcastClientInitializer") - public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() { - return createThreadPoolTaskExecutor(1, true); - } - - @Bean(name = "taskExecutorIdGeneratorAwaiter") - public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() { - return createThreadPoolTaskExecutor(1, false); + return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } @Bean(name = "hazelcastClientParams") @@ -67,7 +70,6 @@ public class HazelcastServiceTestConfiguration { params.setClusterMembers("127.0.0.1"); params.setInstanceName("hzTestClient" + new Random().nextInt()); params.setNearCacheConfig(new NearCacheConfig()); - return params; } -} \ No newline at end of file +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/KafkaTestConfig.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/KafkaTestConfig.java new file mode 100644 index 000000000..5f54dac64 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/KafkaTestConfig.java @@ -0,0 +1,42 @@ +package ru.spcex.clearing.securities.config; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.apache.kafka.clients.consumer.OffsetResetStrategy; +import org.apache.kafka.clients.producer.Producer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.service.RequestInfo; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; + +@Configuration +public class KafkaTestConfig { + + @Autowired + @Bean + public KafkaSender kafkaSender(Producer kafkaProducer, + ImdgProvider imdgProvider) { + ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator(); + return KafkaSender + .setup() + .producer(kafkaProducer) + .idGenerator(imdgIdGenerator::nextId) + .imdgProvider(s -> { + Imdg imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class); + return imdg::insert; + }) + .build(); + } + + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + @Bean + public MockConsumer createTestConsumer() { + return new MockConsumer<>(OffsetResetStrategy.EARLIEST); + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java new file mode 100644 index 000000000..391580ce8 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -0,0 +1,74 @@ +package ru.spcex.clearing.securities.service; + +import org.apache.kafka.clients.producer.MockProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +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.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; +import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; +import ru.clearing.classes.statics.data.misc.Listing; +import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.securities.component.ListingBuilder; +import ru.spcex.clearing.securities.config.ErrorResolverConfig; +import ru.spcex.clearing.securities.config.ImdgTestConfig; +import ru.spcex.clearing.securities.config.KafkaTestConfig; +import ru.spcex.clearing.securities.config.ValidationConfig; +import ru.spcex.clearing.securities.service.cud.EquitySecurityService; +import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; +import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; +import ru.spcex.clearing.securities.utils.MatcherFactory; +import ru.spcex.clearing.securities.utils.TestUtils; +import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.util.concurrent.atomic.AtomicLong; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + EquitySecurityService.class, + FixedIncomeSecurityService.class, + MoneyMarketSecurityService.class, + ImdgTestConfig.class, + KafkaTestConfig.class, + ValidationProvider.class, + ErrorResolverConfig.class, + ValidationConfig.class}) +public abstract class AbstractServiceTest { + protected static final MatcherFactory.Matcher LISTING_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + protected static AtomicLong currentId = new AtomicLong(0L); + protected Imdg moneyMarketSecurityMap; + protected Imdg listingImdg; + protected Imdg equitySecurityImdg; + protected Imdg fixedIncomeSecurityImdg; + protected final ListingBuilder listingBuilder = new ListingBuilder(); + @Captor + protected ArgumentCaptor producerRecord; + @MockBean + protected MockProducer mockProducer; + @Autowired + @Qualifier("hazelcastServiceTest") + protected ImdgProvider imdgProvider; + + protected void init() { + imdgProvider.waitAvailable(); + this.moneyMarketSecurityMap = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class); + this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); + this.fixedIncomeSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java new file mode 100644 index 000000000..960212afc --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java @@ -0,0 +1,210 @@ +package ru.spcex.clearing.securities.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; +import ru.clearing.classes.statics.data.misc.Listing; +import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; +import ru.spcex.clearing.securities.service.cud.EquitySecurityService; +import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; +import ru.spcex.clearing.securities.utils.MatcherFactory; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.util.Map; + +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.securities.utils.TestUtils.*; + +public class EquitySecurityServiceTest extends AbstractServiceTest{ + private static final MatcherFactory.Matcher EQUITY_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + private final long ID = currentId.getAndIncrement(); + private final int PARTITION = 0; + @Autowired + private EquitySecurityService equitySecurityService; + @PostConstruct + protected void init() { + super.init(); + } + + /** + * {@link MoneyMarketSecurityService#newMoneyMarket(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link MoneyMarketSecurityNewRequest}:
+ * {@link MoneyMarketSecurityNewRequest#lotSize} - 1.0
+ * {@link MoneyMarketSecurityNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
+ * {@link MoneyMarketSecurityNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
+ * {@link MoneyMarketSecurityNewRequest#nominalValue} - 1.0
+ * {@link MoneyMarketSecurityNewRequest#nominalCurrency} - 1L
+ * {@link MoneyMarketSecurityNewRequest#instrumentType} - "sdgaga"
+ * {@link MoneyMarketSecurityNewRequest#fullName} - "estat"
+ */ + @Test + public void testNewEquity(){ + final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_NEW; + + final EquitySecurity equityPrediction = getEquitySecurity(); + final EquitySecurityNewRequest request = getEquitySecurityNewRequest(equityPrediction); + Listing listingPrediction = listingBuilder.byNewEquity(equityPrediction, request); + + //ACT + String jsonString = getJsonStringForNew(request, ID); + + addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + EquitySecurity equityResult = equitySecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", equityPrediction.getFullName())); + equityPrediction.setId(equityResult.getId()); + equityPrediction.setSecurityId(equityResult.getSecurityId()); + EQUITY_SECURITY_MATCHER.assertMatch(equityResult, equityPrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equityPrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + /** + * {@link MoneyMarketSecurityService#updateMoneyMarket(BaseRequest)} + * Тест проверяет обновление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link MoneyMarketSecurityUpdateRequest}:
+ * {@link MoneyMarketSecurityUpdateRequest#fullName} - sfgsdfg
+ * {@link MoneyMarketSecurityUpdateRequest#instrumentType} - qwerqwe
+ * {@link MoneyMarketSecurityUpdateRequest#nominalCurrency} - RUB
+ * {@link MoneyMarketSecurityUpdateRequest#nominalValue} - 2.0
+ * {@link MoneyMarketSecurityUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)
+ */ + @Test + public void testUpdateEquity() { + final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_UPDATE; + String fullName = "FullNameUpdate"; + Double updateLotSize = 12.0; + + final EquitySecurity equityPrediction = getEquitySecurity(); + equitySecurityImdg.insert(equityPrediction); + equityPrediction.setFullName(fullName); + equityPrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); + final EquitySecurityUpdateRequest request = getEquitySecurityUpdateRequest(equityPrediction); + Listing listingPrediction = new Listing(); + listingPrediction = listingBuilder.byUpdateEquity(equityPrediction, listingPrediction); + listingImdg.insert(listingPrediction); + + //ACT + String jsonString = getJsonStringForUPDATE(request, ID); + + addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + EquitySecurity equityResult = equitySecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", equityPrediction.getFullName())); + equityPrediction.setId(equityResult.getId()); + equityPrediction.setSecurityId(equityResult.getSecurityId()); + EQUITY_SECURITY_MATCHER.assertMatch(equityResult, equityPrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equityPrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + /** + * {@link MoneyMarketSecurityService#deleteMoneyMarket(BaseRequest)}
+ * Тест проверяет удаление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + public void testDeleteEquity(){ + final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_DELETE; + + final EquitySecurity equityPrediction = getEquitySecurity(); + equitySecurityImdg.insert(equityPrediction); + equityPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + + Listing listingPrediction = new Listing(); + listingPrediction = listingBuilder.byUpdateEquity(equityPrediction, listingPrediction); + listingImdg.insert(listingPrediction);listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + + CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); + commonDeleteRequest.setId(ID); + + //ACT + String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID); + + addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + EquitySecurity equityResult = equitySecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", equityPrediction.getFullName())); + equityPrediction.setId(equityResult.getId()); + equityPrediction.setSecurityId(equityResult.getSecurityId()); + EQUITY_SECURITY_MATCHER.assertMatch(equityResult, equityPrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equityPrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + private EquitySecurity getEquitySecurity(){ + EquitySecurity equitySecurity = new EquitySecurity(); + equitySecurity.setId(ID); + equitySecurity.setSecuritySymbol("SecuritySymbol"); + equitySecurity.setShortName("ShortNameNewEquity"); + equitySecurity.setFullName("FullNameNewEquity"); + equitySecurity.setIsin("Isin"); + equitySecurity.setShareType("ShareType"); + equitySecurity.setLotSize(BigDecimal.valueOf(18.0d)); + equitySecurity.setIssuerId(11L); + equitySecurity.setShortNameEng("ShortNameNewEquity"); + equitySecurity.setFullNameEng("FullNameNewEquity"); + equitySecurity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + equitySecurity.setInstrumentType("EQTY"); + return equitySecurity; + } + + private EquitySecurityNewRequest getEquitySecurityNewRequest(EquitySecurity equitySecurity){ + EquitySecurityNewRequest equitySecurityNewRequest = new EquitySecurityNewRequest(); + equitySecurityNewRequest.setSecuritySymbol(equitySecurity.getSecuritySymbol()); + equitySecurityNewRequest.setShortName(equitySecurity.getShortName()); + equitySecurityNewRequest.setFullName(equitySecurity.getFullName()); + equitySecurityNewRequest.setIsin(equitySecurity.getIsin()); + equitySecurityNewRequest.setShareType(equitySecurity.getShareType()); + equitySecurityNewRequest.setLotSize(equitySecurity.getLotSize().doubleValue()); + equitySecurityNewRequest.setIssuerId(equitySecurity.getIssuerId()); + equitySecurityNewRequest.setShortNameEng(equitySecurity.getShortNameEng()); + equitySecurityNewRequest.setFullNameEng(equitySecurity.getFullNameEng()); + equitySecurityNewRequest.setWorkflowStatus(equitySecurity.getWorkflowStatus()); + equitySecurityNewRequest.setInstrumentType(equitySecurity.getInstrumentType()); + return equitySecurityNewRequest; + } + + private EquitySecurityUpdateRequest getEquitySecurityUpdateRequest(EquitySecurity equitySecurity){ + EquitySecurityUpdateRequest equitySecurityUpdateRequest = new EquitySecurityUpdateRequest(); + equitySecurityUpdateRequest.setId(equitySecurity.getId()); + equitySecurityUpdateRequest.setSecuritySymbol(equitySecurity.getSecuritySymbol()); + equitySecurityUpdateRequest.setShortName(equitySecurity.getShortName()); + equitySecurityUpdateRequest.setFullName(equitySecurity.getFullName()); + equitySecurityUpdateRequest.setIsin(equitySecurity.getIsin()); + equitySecurityUpdateRequest.setShareType(equitySecurity.getShareType()); + equitySecurityUpdateRequest.setLotSize(equitySecurity.getLotSize().doubleValue()); + equitySecurityUpdateRequest.setIssuerId(equitySecurity.getIssuerId()); + equitySecurityUpdateRequest.setShortNameEng(equitySecurity.getShortNameEng()); + equitySecurityUpdateRequest.setFullNameEng(equitySecurity.getFullNameEng()); + equitySecurityUpdateRequest.setWorkflowStatus(equitySecurity.getWorkflowStatus()); + equitySecurityUpdateRequest.setInstrumentType(equitySecurity.getInstrumentType()); + return equitySecurityUpdateRequest; + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java new file mode 100644 index 000000000..9e19f531e --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java @@ -0,0 +1,227 @@ +package ru.spcex.clearing.securities.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; +import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; +import ru.clearing.classes.statics.data.misc.Listing; +import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; +import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; +import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; +import ru.spcex.clearing.securities.utils.MatcherFactory; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Map; + +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.securities.utils.TestUtils.*; + +public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ + private static final MatcherFactory.Matcher FIXED_INCOME_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + private final long ID = currentId.getAndIncrement(); + private final int PARTITION = 0; + @Autowired + private FixedIncomeSecurityService fixedIncomeSecurityService; + @PostConstruct + protected void init() { + super.init(); + } + + /** + * {@link MoneyMarketSecurityService#newMoneyMarket(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link MoneyMarketSecurityNewRequest}:
+ * {@link MoneyMarketSecurityNewRequest#lotSize} - 1.0
+ * {@link MoneyMarketSecurityNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
+ * {@link MoneyMarketSecurityNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
+ * {@link MoneyMarketSecurityNewRequest#nominalValue} - 1.0
+ * {@link MoneyMarketSecurityNewRequest#nominalCurrency} - 1L
+ * {@link MoneyMarketSecurityNewRequest#instrumentType} - "sdgaga"
+ * {@link MoneyMarketSecurityNewRequest#fullName} - "estat"
+ */ + @Test + public void newFixedIncome(){ + final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_NEW; + + final FixedIncomeSecurity fixedIncomePrediction = getFixedIncomeSecurity(); + final FixedIncomeSecurityNewRequest request = getFixedIncomeSecurityNewRequest(fixedIncomePrediction); + Listing listingPrediction = listingBuilder.byNewFixedIncome(fixedIncomePrediction, request); + + //ACT + String jsonString = getJsonStringForNew(request, ID); + + addRecordToKafka((MockConsumer) fixedIncomeSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + FixedIncomeSecurity equityResult = fixedIncomeSecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", fixedIncomePrediction.getFullName())); + fixedIncomePrediction.setId(equityResult.getId()); + fixedIncomePrediction.setSecurityId(equityResult.getSecurityId()); + FIXED_INCOME_SECURITY_MATCHER.assertMatch(equityResult, fixedIncomePrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncomePrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + /** + * {@link MoneyMarketSecurityService#updateMoneyMarket(BaseRequest)} + * Тест проверяет обновление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link MoneyMarketSecurityUpdateRequest}:
+ * {@link MoneyMarketSecurityUpdateRequest#fullName} - sfgsdfg
+ * {@link MoneyMarketSecurityUpdateRequest#instrumentType} - qwerqwe
+ * {@link MoneyMarketSecurityUpdateRequest#nominalCurrency} - RUB
+ * {@link MoneyMarketSecurityUpdateRequest#nominalValue} - 2.0
+ * {@link MoneyMarketSecurityUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)
+ */ + @Test + public void updateFixedIncome() { +// clearAllInImdg(moneyMarketSecurityMap); +// final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_UPDATE; +// String fullName = "FullNameUpdate"; +// Double updateLotSize = 12.0; +// +// final FixedIncomeSecurity fixedIncomePrediction = getFixedIncomeSecurity(); +// +// fixedIncomeSecurityImdg.insert(fixedIncomePrediction); +// fixedIncomePrediction.setFullName(fullName); +// fixedIncomePrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); +// final FixedIncomeSecurityUpdateRequest request = getEquitySecurityUpdateRequest(fixedIncomePrediction); +// Listing listingPrediction = new Listing(); +// listingPrediction = listingBuilder.byUpdateEquity(fixedIncomePrediction, listingPrediction); +// listingImdg.insert(listingPrediction); +// +// //ACT +// String jsonString = getJsonStringForUPDATE(request, ID); +// +// addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); +// +// //ASSERT +// waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); +// +// EquitySecurity equityResult = equitySecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", fixedIncomePrediction.getFullName())); +// fixedIncomePrediction.setId(equityResult.getId()); +// fixedIncomePrediction.setSecurityId(equityResult.getSecurityId()); +// FIXED_INCOME_SECURITY_MATCHER.assertMatch(equityResult, fixedIncomePrediction); +// +// Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncomePrediction.getId())); +// listingPrediction.setId(listingResult.getId()); +// listingPrediction.setSecurityId(listingResult.getSecurityId()); +// LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + /** + * {@link MoneyMarketSecurityService#deleteMoneyMarket(BaseRequest)}
+ * Тест проверяет удаление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + public void deleteFixedIncome(){ +// clearAllInImdg(moneyMarketSecurityMap); +// final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_DELETE; +// +// final EquitySecurity equityPrediction = getFixedIncomeSecurity(); +// equitySecurityImdg.insert(equityPrediction); +// equityPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); +// +// Listing listingPrediction = new Listing(); +// listingPrediction = listingBuilder.byUpdateEquity(equityPrediction, listingPrediction); +// listingImdg.insert(listingPrediction);listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); +// +// CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); +// commonDeleteRequest.setId(ID); +// +// //ACT +// String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID); +// +// addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); +// +// //ASSERT +// waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); +// +// EquitySecurity equityResult = equitySecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", equityPrediction.getFullName())); +// equityPrediction.setId(equityResult.getId()); +// equityPrediction.setSecurityId(equityResult.getSecurityId()); +// FIXED_INCOME_SECURITY_MATCHER.assertMatch(equityResult, equityPrediction); +// +// Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equityPrediction.getId())); +// listingPrediction.setId(listingResult.getId()); +// listingPrediction.setSecurityId(listingResult.getSecurityId()); +// LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + private FixedIncomeSecurity getFixedIncomeSecurity(){ + FixedIncomeSecurity fixedIncome = new FixedIncomeSecurity(); + fixedIncome.setId(ID); + fixedIncome.setSecuritySymbol("SecuritySymbol"); + fixedIncome.setShortName("ShortNameNewEquity"); + fixedIncome.setFullName("FullNameNewEquity"); + fixedIncome.setIsin("Isin"); + fixedIncome.setBondType("BondType"); + fixedIncome.setLotSize(BigDecimal.valueOf(18.0d)); + fixedIncome.setNominalValue(BigDecimal.valueOf(18.0d)); + fixedIncome.setNominalCurrency("NominalCurrency"); + fixedIncome.setMaturityDate(LocalDate.now()); + fixedIncome.setCoupon(BigDecimal.valueOf(18.0d)); + fixedIncome.setCouponFrequency(9L); + fixedIncome.setIssuerId(11L); + fixedIncome.setShortNameEng("ShortNameNewEquity"); + fixedIncome.setFullNameEng("FullNameNewEquity"); + fixedIncome.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + fixedIncome.setInstrumentType("BOND"); + fixedIncome.setSecurityId(fixedIncome.getId()); + + return fixedIncome; + } + + private FixedIncomeSecurityNewRequest getFixedIncomeSecurityNewRequest(FixedIncomeSecurity fixedIncomeSecurity){ + FixedIncomeSecurityNewRequest equitySecurityNewRequest = new FixedIncomeSecurityNewRequest(); + equitySecurityNewRequest.setSecuritySymbol(fixedIncomeSecurity.getSecuritySymbol()); + equitySecurityNewRequest.setShortName(fixedIncomeSecurity.getShortName()); + equitySecurityNewRequest.setFullName(fixedIncomeSecurity.getFullName()); + equitySecurityNewRequest.setIsin(fixedIncomeSecurity.getIsin()); + equitySecurityNewRequest.setBondType(fixedIncomeSecurity.getBondType()); + equitySecurityNewRequest.setLotSize(fixedIncomeSecurity.getLotSize().doubleValue()); + equitySecurityNewRequest.setNominalValue(fixedIncomeSecurity.getNominalValue().doubleValue()); + equitySecurityNewRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); + equitySecurityNewRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); + equitySecurityNewRequest.setCoupon(fixedIncomeSecurity.getCoupon().doubleValue()); + equitySecurityNewRequest.setCouponFrequency(9L); + equitySecurityNewRequest.setIssuerId(fixedIncomeSecurity.getIssuerId()); + equitySecurityNewRequest.setShortNameEng(fixedIncomeSecurity.getShortNameEng()); + equitySecurityNewRequest.setFullNameEng(fixedIncomeSecurity.getFullNameEng()); + equitySecurityNewRequest.setWorkflowStatus(fixedIncomeSecurity.getWorkflowStatus()); + equitySecurityNewRequest.setInstrumentType(fixedIncomeSecurity.getInstrumentType()); + return equitySecurityNewRequest; + } + + private EquitySecurityUpdateRequest getEquitySecurityUpdateRequest(EquitySecurity equitySecurity){ + EquitySecurityUpdateRequest equitySecurityUpdateRequest = new EquitySecurityUpdateRequest(); + equitySecurityUpdateRequest.setId(equitySecurity.getId()); + equitySecurityUpdateRequest.setSecuritySymbol(equitySecurity.getSecuritySymbol()); + equitySecurityUpdateRequest.setShortName(equitySecurity.getShortName()); + equitySecurityUpdateRequest.setFullName(equitySecurity.getFullName()); + equitySecurityUpdateRequest.setIsin(equitySecurity.getIsin()); + equitySecurityUpdateRequest.setShareType(equitySecurity.getShareType()); + equitySecurityUpdateRequest.setLotSize(equitySecurity.getLotSize().doubleValue()); + equitySecurityUpdateRequest.setIssuerId(equitySecurity.getIssuerId()); + equitySecurityUpdateRequest.setShortNameEng(equitySecurity.getShortNameEng()); + equitySecurityUpdateRequest.setFullNameEng(equitySecurity.getFullNameEng()); + equitySecurityUpdateRequest.setWorkflowStatus(equitySecurity.getWorkflowStatus()); + equitySecurityUpdateRequest.setInstrumentType(equitySecurity.getInstrumentType()); + return equitySecurityUpdateRequest; + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java index 86675c716..fd66d5950 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java @@ -16,11 +16,17 @@ class MoneyMarketSecurityFactory { private String description = "tsetse"; private Double lotSize = 1.0; private LocalDate startDate = LocalDate.ofEpochDay(0); - private LocalDate endDate = LocalDate.ofEpochDay(0); + private LocalDate endDate = LocalDate.now(); private BigDecimal nominalValue = BigDecimal.valueOf(1.0); - private String instrumentType = "sdgaga"; // (linked to instrumentType) + private String instrumentType = "RATE"; // (linked to instrumentType) private String fullName = "estat"; + private String shortName = "esasdftat"; private String securitySymbol = "sdfafd"; + private String termType = "termType"; + + public String getFullName() { + return fullName; + } public MoneyMarketSecurityFactory setLotSize(Double lotSize) { this.lotSize = lotSize; @@ -89,7 +95,12 @@ class MoneyMarketSecurityFactory { moneyMarketSecurity.setNominalCurrency(nominalCurrency); moneyMarketSecurity.setInstrumentType(instrumentType); moneyMarketSecurity.setFullName(fullName); + moneyMarketSecurity.setShortName(shortName); + moneyMarketSecurity.setTermType(termType); + moneyMarketSecurity.setDescription(description); + moneyMarketSecurity.setLotSize(BigDecimal.valueOf(lotSize)); moneyMarketSecurity.setSecuritySymbol(securitySymbol); + moneyMarketSecurity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); return moneyMarketSecurity; } @@ -99,11 +110,17 @@ class MoneyMarketSecurityFactory { = new MoneyMarketSecurityUpdateRequest(); moneyMarketSecurityUpdateRequest.setId(id); + moneyMarketSecurityUpdateRequest.setLotSize(lotSize); + moneyMarketSecurityUpdateRequest.setStartDate(startDate); moneyMarketSecurityUpdateRequest.setEndDate(endDate); moneyMarketSecurityUpdateRequest.setNominalValue(nominalValue.doubleValue()); moneyMarketSecurityUpdateRequest.setNominalCurrency(nominalCurrency); moneyMarketSecurityUpdateRequest.setInstrumentType(instrumentType); moneyMarketSecurityUpdateRequest.setFullName(fullName); + moneyMarketSecurityUpdateRequest.setShortName(shortName); + moneyMarketSecurityUpdateRequest.setTermType(termType); + moneyMarketSecurityUpdateRequest.setDescription(description); + moneyMarketSecurityUpdateRequest.setSecuritySymbol(securitySymbol); return moneyMarketSecurityUpdateRequest; } @@ -124,6 +141,9 @@ class MoneyMarketSecurityFactory { keyRequest.setNominalCurrency(nominalCurrency); keyRequest.setInstrumentType(instrumentType); keyRequest.setFullName(fullName); + keyRequest.setShortName(shortName); + keyRequest.setTermType(termType); + keyRequest.setDescription(description); keyRequest.setSecuritySymbol(securitySymbol); return keyRequest; diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceDisabled.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceDisabled.java deleted file mode 100644 index 971c65732..000000000 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceDisabled.java +++ /dev/null @@ -1,324 +0,0 @@ -package ru.spcex.clearing.securities.service; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.hazelcast.core.HazelcastInstance; -import com.hazelcast.core.IMap; -import com.hazelcast.map.listener.EntryAddedListener; -import com.hazelcast.map.listener.EntryRemovedListener; -import com.hazelcast.map.listener.EntryUpdatedListener; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.consumer.MockConsumer; -import org.apache.kafka.clients.consumer.OffsetResetStrategy; -import org.apache.kafka.clients.producer.MockProducer; -import org.apache.kafka.common.TopicPartition; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import ru.clearing.classes.statics.data.misc.KeyRate; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; -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.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; -import ru.spcex.clearing.securities.config.HazelcastInstanceTestConfiguration; -import ru.spcex.clearing.securities.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; -import ru.spcex.clearing.securities.utils.MatcherFactory; -import ru.spcex.clearing.securities.validation.ValidationProvider; -import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; -import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; - -import java.math.BigDecimal; -import java.time.LocalDate; -import java.util.Collections; -import java.util.HashMap; - -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = { - HazelcastServiceTestConfiguration.class, - HazelcastInstanceTestConfiguration.class}) -public class MoneyMarketSecurityServiceDisabled { - static final ObjectMapper objectMapper = new ObjectMapper(); - private final int TIMEOUT = 1000; - boolean isUsed; - private MockConsumer kafkaMockQueue; - private final MockProducer mockProducer = new MockProducer<>(); - // @Autowired -// @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastService; - // @Autowired -// @Qualifier("hazelcastInstance") - private HazelcastInstance hz; - - private void setIsUsed(boolean isUsed) { - this.isUsed = isUsed; - } - - private String jsonBaseRequest(BaseRequest baseRequest) { - String jsonBaseRequest; - - try { - jsonBaseRequest = objectMapper.writeValueAsString(baseRequest); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - - return jsonBaseRequest; - } - - void initKafka(String topic, int partition, Long offset) { - TopicPartition tp = new TopicPartition(topic, partition); - - kafkaMockQueue.schedulePollTask(() -> { - kafkaMockQueue.rebalance(Collections.singletonList(tp)); - }); - - HashMap startOffsets = new HashMap<>(); - startOffsets.put(tp, offset); - - kafkaMockQueue.updateBeginningOffsets(startOffsets); - } - - private void startService() throws InterruptedException { - MoneyMarketSecurityService keyRateService = - new MoneyMarketSecurityService(kafkaMockQueue, mockProducer, hazelcastService, - new ValidationProvider(hazelcastService), new SimpleMessageResolver()); - keyRateService.afterPropertiesSet(); - } - - /** - * {@link MoneyMarketSecurityService#newMoneyMarket(BaseRequest)}
- * Тест проверяет генерацию сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link MoneyMarketSecurityNewRequest}:
- * {@link MoneyMarketSecurityNewRequest#lotSize} - 1.0
- * {@link MoneyMarketSecurityNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
- * {@link MoneyMarketSecurityNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
- * {@link MoneyMarketSecurityNewRequest#nominalValue} - 1.0
- * {@link MoneyMarketSecurityNewRequest#nominalCurrency} - 1L
- * {@link MoneyMarketSecurityNewRequest#instrumentType} - "sdgaga"
- * {@link MoneyMarketSecurityNewRequest#fullName} - "estat"
- */ -// @Test - public void testNewMoneyMarketSecurity() throws InterruptedException { - final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW; - final String MAP = IMDGDistributedNames.Map_MoneyMarketSecurity; - - final int PARTITION = 0; - final Long OFFSET = 0L; - final Long REQUEST_ID = 0L; - - final MoneyMarketSecurityFactory moneyMarketSecurityFactory = new MoneyMarketSecurityFactory(); - - final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory - .getMoneyMarketSecurity(); - final MoneyMarketSecurityNewRequest keyRequest = moneyMarketSecurityFactory - .getMoneyMarketSecurityNewRequest(); - - BaseRequest baseRequest = new BaseRequest(); - - baseRequest.setRequestPayload(keyRequest); - baseRequest.setId(REQUEST_ID); - baseRequest.setActionType(ActionType.NEW); - - String jsonRequest = jsonBaseRequest(baseRequest); - - ConsumerRecord consumerRecord = - new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest); - - kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST); - initKafka(TOPIC, PARTITION, OFFSET); - - kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord)); - - isUsed = false; - - IMap iMap = hz.getMap(MAP); - - Object waiter = new Object(); - - String listenerID = iMap.addEntryListener((EntryAddedListener) entryEvent -> { - System.out.println("Checking Equality"); - MoneyMarketSecurity moneyMarketSecurityResult = entryEvent.getValue(); - moneyMarketSecurityPrediction.setId(entryEvent.getKey()); - - MatcherFactory.Matcher matcher = MatcherFactory - .usingIgnoringFieldsComparator("id", "securityId", "description"); - matcher.assertMatch(moneyMarketSecurityResult, moneyMarketSecurityPrediction); - System.out.println("ok"); - setIsUsed(true); - synchronized (waiter) { - waiter.notify(); - } - }, true); - - startService(); - - synchronized (waiter) { - waiter.wait(TIMEOUT); - } - - Assertions.assertEquals(true, isUsed); - iMap.removeEntryListener(listenerID); - } - - /** - * {@link MoneyMarketSecurityService#deleteMoneyMarket(BaseRequest)}
- * Тест проверяет удаление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link CommonDeleteRequest}:
- * {@link CommonDeleteRequest#id} - Идентификатор записи
- */ -// @Test - public void testDeleteKeyRate() throws InterruptedException { - final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE; - final String MAP = IMDGDistributedNames.Map_MoneyMarketSecurity; - - final int PARTITION = 0; - final Long ID = 1L; - final Long OFFSET = 0L; - final Long REQUEST_ID = 2L; - - final MoneyMarketSecurityFactory moneyMarketSecurityFactory = - new MoneyMarketSecurityFactory() - .setId(ID); - - final MoneyMarketSecurity initialMoneyMarketSecurity = moneyMarketSecurityFactory - .getMoneyMarketSecurity(); - final CommonDeleteRequest keyRequest = moneyMarketSecurityFactory - .getCommonDeleteRequest(); - - BaseRequest baseRequest = new BaseRequest(); - - baseRequest.setRequestPayload(keyRequest); - baseRequest.setId(REQUEST_ID); - baseRequest.setActionType(ActionType.DELETE); - - String jsonRequest = jsonBaseRequest(baseRequest); - - ConsumerRecord consumerRecord = - new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest); - - kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST); - initKafka(TOPIC, PARTITION, OFFSET); - - kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord)); - - isUsed = false; - - IMap iMap = hz.getMap(MAP); - iMap.put(ID, initialMoneyMarketSecurity); - - Object waiter = new Object(); - String listenerID = iMap.addEntryListener((EntryRemovedListener) entryEvent -> { - System.out.println("Checking If removed.."); - Assertions.assertEquals(ID, entryEvent.getKey()); - System.out.println("ok"); - setIsUsed(true); - synchronized (waiter) { - waiter.notify(); - } - }, false); - - startService(); - - synchronized (waiter) { - waiter.wait(TIMEOUT); - } - - Assertions.assertEquals(true, isUsed); - iMap.removeEntryListener(listenerID); - } - - /** - * {@link MoneyMarketSecurityService#updateMoneyMarket(BaseRequest)} - * Тест проверяет обновление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link MoneyMarketSecurityUpdateRequest}:
- * {@link MoneyMarketSecurityUpdateRequest#fullName} - sfgsdfg
- * {@link MoneyMarketSecurityUpdateRequest#instrumentType} - qwerqwe
- * {@link MoneyMarketSecurityUpdateRequest#nominalCurrency} - RUB
- * {@link MoneyMarketSecurityUpdateRequest#nominalValue} - 2.0
- * {@link MoneyMarketSecurityUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)
- */ -// @Test - public void testUpdateKeyRate() throws InterruptedException { - final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE; - final String MAP = IMDGDistributedNames.Map_MoneyMarketSecurity; - - final int PARTITION = 0; - final Long ID = 1L; - final Long OFFSET = 0L; - final Long REQUEST_ID = 1L; - - final MoneyMarketSecurityFactory moneyMarketSecurityFactory = - new MoneyMarketSecurityFactory() - .setId(ID); - - final MoneyMarketSecurity initialMoneyMarketSecurity = moneyMarketSecurityFactory - .getMoneyMarketSecurity(); - - moneyMarketSecurityFactory - .setFullName("sfgsdfg") - .setInstrumentType("qwerqwe") - .setNominalCurrency("RUB") - .setNominalValue(BigDecimal.valueOf(2.0)) - .setEndDate(LocalDate.ofEpochDay(24 * 3600)); - - final MoneyMarketSecurity moneyMarketSecurityPrediction = - moneyMarketSecurityFactory.getMoneyMarketSecurity(); - final MoneyMarketSecurityUpdateRequest keyRequest = - moneyMarketSecurityFactory.getMoneyMarketSecurityUpdateRequest(); - - BaseRequest baseRequest = new BaseRequest(); - - baseRequest.setRequestPayload(keyRequest); - baseRequest.setId(REQUEST_ID); - baseRequest.setActionType(ActionType.UPDATE); - - String jsonRequest = jsonBaseRequest(baseRequest); - - ConsumerRecord consumerRecord = - new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest); - - kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST); - initKafka(TOPIC, PARTITION, OFFSET); - - kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord)); - - IMap iMap = hz.getMap(MAP); - iMap.put(ID, initialMoneyMarketSecurity); - - isUsed = false; - - Object waiter = new Object(); - String listenerID = iMap.addEntryListener((EntryUpdatedListener) entryEvent -> { - System.out.println("Checking Equality.."); - MoneyMarketSecurity moneyMarketSecurityResult = entryEvent.getValue(); - - MatcherFactory.Matcher matcher = MatcherFactory - .usingIgnoringFieldsComparator("id"); - - matcher.assertMatch(moneyMarketSecurityResult, moneyMarketSecurityPrediction); - - System.out.println("Ok"); - setIsUsed(true); - - synchronized (waiter) { - waiter.notify(); - } - }, true); - - startService(); - - synchronized (waiter) { - waiter.wait(TIMEOUT); - } - - Assertions.assertEquals(true, isUsed); - iMap.removeEntryListener(listenerID); - } - -} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java new file mode 100644 index 000000000..2f95ecb3e --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java @@ -0,0 +1,179 @@ +package ru.spcex.clearing.securities.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import ru.clearing.classes.statics.data.misc.Listing; +import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.RequestInfo; +import ru.spcex.clearing.platform.messaging.service.Status; +import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; +import ru.spcex.clearing.securities.utils.MatcherFactory; +import ru.spcex.platform.imdg.api.Imdg; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.util.Map; + +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.securities.utils.TestUtils.*; + +public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{ + private static final MatcherFactory.Matcher MONEY_MARKET_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + private final long ID = currentId.getAndIncrement(); + private final int PARTITION = 0; + private MoneyMarketSecurityFactory moneyMarketSecurityFactory; + @Autowired + private MoneyMarketSecurityService moneyMarketSecurityService; + @PostConstruct + protected void init() { + super.init(); + Imdg requestSpecificImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class); + RequestInfo requestFound = new RequestInfo(); + requestFound.setId(ID); + requestFound.setStatus(Status.Processing); + requestSpecificImdg.insert(requestFound); + moneyMarketSecurityFactory = new MoneyMarketSecurityFactory(); + moneyMarketSecurityFactory.setId(ID); + } + + /** + * {@link MoneyMarketSecurityService#newMoneyMarket(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link MoneyMarketSecurityNewRequest}:
+ * {@link MoneyMarketSecurityNewRequest#lotSize} - 1.0
+ * {@link MoneyMarketSecurityNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
+ * {@link MoneyMarketSecurityNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
+ * {@link MoneyMarketSecurityNewRequest#nominalValue} - 1.0
+ * {@link MoneyMarketSecurityNewRequest#nominalCurrency} - 1L
+ * {@link MoneyMarketSecurityNewRequest#instrumentType} - "sdgaga"
+ * {@link MoneyMarketSecurityNewRequest#fullName} - "estat"
+ */ + @Test + public void testNewMoneyMarketSecurity(){ + clearAllInImdg(moneyMarketSecurityMap); + final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW; + + final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory + .getMoneyMarketSecurity(); + final MoneyMarketSecurityNewRequest keyRequest = moneyMarketSecurityFactory + .getMoneyMarketSecurityNewRequest(); + Listing listingPrediction = listingBuilder.byNewMms(moneyMarketSecurityPrediction, keyRequest); + + //ACT + String jsonString = getJsonStringForNew(keyRequest, ID); + + addRecordToKafka((MockConsumer) moneyMarketSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + MoneyMarketSecurity moneyMarketSecurityResult = moneyMarketSecurityMap.getSingleObjectBySQL(String.format("fullName = %s", moneyMarketSecurityFactory.getFullName())); + moneyMarketSecurityPrediction.setId(moneyMarketSecurityResult.getId()); + moneyMarketSecurityPrediction.setSecurityId(moneyMarketSecurityResult.getSecurityId()); + MONEY_MARKET_SECURITY_MATCHER.assertMatch(moneyMarketSecurityResult, moneyMarketSecurityPrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", moneyMarketSecurityPrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + /** + * {@link MoneyMarketSecurityService#deleteMoneyMarket(BaseRequest)}
+ * Тест проверяет удаление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + public void testDeleteMoneyMarket(){ + clearAllInImdg(moneyMarketSecurityMap); + final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE; + + final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory + .getMoneyMarketSecurity(); + moneyMarketSecurityMap.insert(moneyMarketSecurityPrediction); + moneyMarketSecurityPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + + Listing listingPrediction = new Listing(); + listingPrediction = listingBuilder.byUpdateMms(moneyMarketSecurityPrediction, listingPrediction); + listingImdg.insert(listingPrediction); + listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + + CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); + commonDeleteRequest.setId(ID); + + //ACT + String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID); + + addRecordToKafka((MockConsumer) moneyMarketSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + MoneyMarketSecurity moneyMarketSecurityResult = moneyMarketSecurityMap.getSingleObjectBySQL(String.format("fullName = %s", moneyMarketSecurityFactory.getFullName())); + moneyMarketSecurityPrediction.setId(moneyMarketSecurityResult.getId()); + MONEY_MARKET_SECURITY_MATCHER.assertMatch(moneyMarketSecurityResult, moneyMarketSecurityPrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", moneyMarketSecurityPrediction.getId())); + listingPrediction.setId(listingResult.getId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + + /** + * {@link MoneyMarketSecurityService#updateMoneyMarket(BaseRequest)} + * Тест проверяет обновление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link MoneyMarketSecurityUpdateRequest}:
+ * {@link MoneyMarketSecurityUpdateRequest#fullName} - sfgsdfg
+ * {@link MoneyMarketSecurityUpdateRequest#instrumentType} - qwerqwe
+ * {@link MoneyMarketSecurityUpdateRequest#nominalCurrency} - RUB
+ * {@link MoneyMarketSecurityUpdateRequest#nominalValue} - 2.0
+ * {@link MoneyMarketSecurityUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)
+ */ + @Test + public void testUpdateMoneyMarket() { + clearAllInImdg(moneyMarketSecurityMap); + final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE; + String updateTermType = "updateTermType"; + Double updateLotSize = 12.0; + + final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory + .getMoneyMarketSecurity(); + moneyMarketSecurityMap.insert(moneyMarketSecurityPrediction); + moneyMarketSecurityPrediction.setTermType(updateTermType); + moneyMarketSecurityPrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); + final MoneyMarketSecurityUpdateRequest keyRequest = moneyMarketSecurityFactory + .getMoneyMarketSecurityUpdateRequest(); + keyRequest.setTermType(updateTermType); + keyRequest.setLotSize(updateLotSize); + Listing listingPrediction = new Listing(); + listingPrediction = listingBuilder.byUpdateMms(moneyMarketSecurityPrediction, listingPrediction); + listingImdg.insert(listingPrediction); + listingPrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); + + //ACT + String jsonString = getJsonStringForUPDATE(keyRequest, ID); + + addRecordToKafka((MockConsumer) moneyMarketSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + MoneyMarketSecurity moneyMarketSecurityResult = moneyMarketSecurityMap.getSingleObjectBySQL(String.format("fullName = %s", moneyMarketSecurityFactory.getFullName())); + moneyMarketSecurityPrediction.setId(moneyMarketSecurityResult.getId()); + moneyMarketSecurityPrediction.setSecurityId(moneyMarketSecurityResult.getSecurityId()); + MONEY_MARKET_SECURITY_MATCHER.assertMatch(moneyMarketSecurityResult, moneyMarketSecurityPrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", moneyMarketSecurityPrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + } + +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/TestUtils.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/TestUtils.java new file mode 100644 index 000000000..c34e15531 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/TestUtils.java @@ -0,0 +1,123 @@ +package ru.spcex.clearing.securities.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.MockConsumer; +import org.apache.kafka.clients.producer.MockProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.apache.kafka.common.TopicPartition; +import org.mockito.ArgumentCaptor; +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.service.RequestInfoUpdate; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; +import static ru.spcex.clearing.platform.messaging.service.Status.Success; +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; + +public class TestUtils { + public static final MatcherFactory.Matcher> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(); + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static void waitingWhenAddedRecordAndCheckIt(Long id, MockProducer mockProducer, ArgumentCaptor producerRecord) { + BaseRequest predictableBaseRequest = new BaseRequest<>(); + predictableBaseRequest.setId(id); + predictableBaseRequest.setActionType(ActionType.SYSTEM); + RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate(); + requestInfoUpdate.setId(id); + requestInfoUpdate.setStatus(Success); + predictableBaseRequest.setRequestPayload(requestInfoUpdate); + + //waiting for kafka producer send message (finale event) + verify(mockProducer, timeout(30_000L).times(1)) + .send(producerRecord.capture()); + + BaseRequest baseRequestResult = (BaseRequest) producerRecord.getValue().value(); + assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic()); + BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); + } + + public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) { + TopicPartition tp = new TopicPartition(topic, partition); + HashMap startOffsets = new HashMap<>(); + startOffsets.put(tp, 0L); + mockConsumer.updateBeginningOffsets(startOffsets); + mockConsumer.schedulePollTask(() -> { + mockConsumer.rebalance(Collections.singletonList(tp)); + mockConsumer.addRecord(new ConsumerRecord<>(topic, partition, offset, "key", jsonValue)); + }); + } + + public static String getJsonStringForNew(T accountRequest, long id) { + return getJsonBaseRequest(accountRequest, id, ActionType.NEW); + } + + public static String getJsonStringForUPDATE(T accountRequest, long id) { + return getJsonBaseRequest(accountRequest, id, ActionType.UPDATE); + } + + public static String getJsonStringForDELETE(T accountRequest, long id) { + return getJsonBaseRequest(accountRequest, id, ActionType.DELETE); + } + + private static String getJsonBaseRequest(T accountRequest, long id, ActionType actionType) { + BaseRequest baseRequest = new BaseRequest<>(); + baseRequest.setRequestPayload(accountRequest); + baseRequest.setId(id); + baseRequest.setActionType(actionType); + String jsonBaseRequest; + try { + jsonBaseRequest = objectMapper.writeValueAsString(baseRequest); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + return jsonBaseRequest; + } + + public static void clearAllInImdg(Imdg imdg) { + Collection values = imdg.getAllValues(); + values.forEach(imdg::delete); + } + + public static class FutureRecordMetadata implements Future { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public boolean isDone() { + return false; + } + + @Override + public RecordMetadata get() throws InterruptedException, ExecutionException { + return null; + } + + @Override + public RecordMetadata get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return null; + } + } +} From ffcba02af2888e3106dea21f8071efc9702b1e29 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 4 Apr 2023 18:22:38 +0300 Subject: [PATCH 28/90] =?UTF-8?q?CLS-259=20CompanyService=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../company/config/BeanConfiguration.java | 21 ------------------- .../company/service/CompanyServiceTest.java | 1 - 2 files changed, 22 deletions(-) delete mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java deleted file mode 100644 index cec73efc2..000000000 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/BeanConfiguration.java +++ /dev/null @@ -1,21 +0,0 @@ -package ru.spcex.clearing.company.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import ru.spcex.clearing.util.security.UserRoleVerification; -import ru.spcex.platform.imdg.api.ImdgProvider; -import ru.spcex.platform.utils.enumeration.IMessageResolver; -import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; - -@Configuration -public class BeanConfiguration { - @Bean - public IMessageResolver messageResolver() { - return new SimpleMessageResolver(); - } - - @Bean - UserRoleVerification userRoleVerification(ImdgProvider imdg) { - return new UserRoleVerification(imdg); - } -} 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 84ce45c8a..e2519cd26 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 @@ -14,7 +14,6 @@ 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.classes.statics.data.generated.ClearingMemberCategory; import ru.clearing.platform.dictionary.CompanySymbolDictionary; import ru.clearing.platform.dictionary.WorkflowStatusDictionary; From 77c4fe1bfdcf84cd7f435a0b8b50b435abec2244 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 4 Apr 2023 18:54:59 +0300 Subject: [PATCH 29/90] fix security-util pom --- clearing-parent/security-util/pom.xml | 60 +-------------------------- 1 file changed, 2 insertions(+), 58 deletions(-) diff --git a/clearing-parent/security-util/pom.xml b/clearing-parent/security-util/pom.xml index c715d998a..4a9abfe93 100644 --- a/clearing-parent/security-util/pom.xml +++ b/clearing-parent/security-util/pom.xml @@ -5,7 +5,8 @@ 4.0.0 security-util - Clearing misc util for verify user roles + security-util clearing + Clearing misc util for verify user roles jar SPCEX-1.0.0.0 @@ -83,61 +84,4 @@ test - - - - src/main/resources - - application.properties - - false - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - ru.spcex.clearing.imdg.IMDGApplication - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - true - ${project.artifactId} - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.21.0 - - - org.junit.platform - junit-platform-surefire-provider - 1.2.0-M1 - - - org.junit.jupiter - junit-jupiter-engine - 5.2.0-M1 - - - - - \ No newline at end of file From a2cc3945f6f4f7ed7f201159cca77a9c61145aba Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 4 Apr 2023 19:04:09 +0300 Subject: [PATCH 30/90] Refactoring: IErrorEnumId --- .../clearing/account/errors/AccountError.java | 4 ++-- .../backendapi/errors/BackEndError.java | 4 ++-- .../clearing/balance/errors/BalanceError.java | 4 ++-- .../clearing/error/ClearingErrorInternal.java | 4 ++-- .../common/rules/DateNotBeforeRule.java | 14 +++++------ .../common/rules/DictionaryPresentRule.java | 14 +++++------ .../common/rules/EndDtAfterStartDtRule.java | 14 +++++------ .../common/rules/EnumPresentRule.java | 14 +++++------ .../common/rules/FieldRequiredRule.java | 6 ++--- .../common/rules/IdPresentRule.java | 24 +++++++++---------- .../common/rules/TimeNotBeforeRule.java | 14 +++++------ .../clearing/company/error/CompanyErrors.java | 4 ++-- .../scheduler/error/ValidationError.java | 4 ++-- .../securities/errors/SecuritiesError.java | 4 ++-- .../rule/IsValidInstrumentTypeById.java | 6 ++--- .../IsValidInstrumentTypeFromRequest.java | 6 ++--- ...BySecuritySymbolAndWorkflowStatusActv.java | 6 ++--- .../imdg/validation/rule/PresentById.java | 8 +++---- .../utils/enumeration/IErrorEnumId.java | 5 ++++ .../utils/validation/IValidationRule.java | 6 ++--- .../utils/validation/TestEnumWithId.java | 3 ++- 21 files changed, 87 insertions(+), 81 deletions(-) create mode 100644 platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/enumeration/IErrorEnumId.java 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 eea8a185e..122609131 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 @@ -1,8 +1,8 @@ package ru.spcex.clearing.account.errors; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum AccountError implements IEnumId { +public enum AccountError implements IErrorEnumId { WrongFieldValue(5004L), AccountAlreadyExist(5010L), CompanyNotFound(5013L), diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java index 8508e0778..03bb9fcd0 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/errors/BackEndError.java @@ -1,8 +1,8 @@ package ru.spcex.clearing.backendapi.errors; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum BackEndError implements IEnumId { +public enum BackEndError implements IErrorEnumId { ValidationError(9000L), UnknownJsonProperty(9001L), FailedToReadHttpMessage(9002L), diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/errors/BalanceError.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/errors/BalanceError.java index 773623c19..e933afed2 100644 --- a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/errors/BalanceError.java +++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/errors/BalanceError.java @@ -1,8 +1,8 @@ package ru.spcex.clearing.balance.errors; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum BalanceError implements IEnumId { +public enum BalanceError implements IErrorEnumId { CompanyNotFound(5211L), CurrencyNotFound(5213L), CurrentDateOnly(5214L), diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java index dfeee61f9..559837733 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java @@ -1,8 +1,8 @@ package ru.spcex.clearing.error; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum ClearingErrorInternal implements IEnumId { +public enum ClearingErrorInternal implements IErrorEnumId { ClearingNotAllowed(1L), AccountNotActive(2L), CompanyNotActive(3L), diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java index df682c6ea..a22834156 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java @@ -2,7 +2,7 @@ package ru.spcex.clearing.validation.common.rules; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.time.LocalDate; @@ -16,8 +16,8 @@ import java.util.function.Function; public record DateNotBeforeRule( String fieldName, Function getter, - IEnumId errorEmptyRequiredValue, - IEnumId errorTaskForPastDate, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastDate, boolean required ) implements IValidationRule> { @@ -31,8 +31,8 @@ public record DateNotBeforeRule( */ public static DateNotBeforeRule instance(String fieldName, Function getter, - IEnumId errorEmptyRequiredValue, - IEnumId errorTaskForPastDate, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastDate, boolean required) { return new DateNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastDate, required); } @@ -46,8 +46,8 @@ public record DateNotBeforeRule( */ public static DateNotBeforeRule instance(String fieldName, Function getter, - IEnumId errorEmptyRequiredValue, - IEnumId errorTaskForPastDate) { + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastDate) { return new DateNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastDate, true); } diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java index ab42f8bc0..9cae88bc0 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -6,7 +6,7 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Collection; @@ -22,8 +22,8 @@ public record DictionaryPresentRule(String fiel Function getter, String dictionaryName, Class dictionaryClass, - IEnumId errorEmptyRequiredValue, - IEnumId errorWrongDictionaryValue, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorWrongDictionaryValue, boolean required) implements IValidationRule> { /** @@ -41,8 +41,8 @@ public record DictionaryPresentRule(String fiel Function getter, String dictionaryName, Class dictionaryClass, - IEnumId errorEmptyRequiredValue, - IEnumId errorWrongDictionaryValue, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorWrongDictionaryValue, boolean required) { return new DictionaryPresentRule<>(fieldName, getter, @@ -67,8 +67,8 @@ public record DictionaryPresentRule(String fiel Function getter, String dictionaryName, Class dictionaryClass, - IEnumId errorEmptyRequiredValue, - IEnumId errorWrongDictionaryValue) { + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorWrongDictionaryValue) { return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java index 909dc97e8..169e5589f 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java @@ -2,7 +2,7 @@ package ru.spcex.clearing.validation.common.rules; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.time.LocalDate; @@ -18,8 +18,8 @@ public record EndDtAfterStartDtRule( String startDtFieldName, Function getterEndDt, Function getterStartDt, - IEnumId errorEmptyRequiredValue, - IEnumId errorEndDtAfterStartDt, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorEndDtAfterStartDt, boolean required ) implements IValidationRule> { @@ -37,8 +37,8 @@ public record EndDtAfterStartDtRule( String startDtFieldName, Function getterEndDt, Function getterStartDt, - IEnumId errorEmptyRequiredValue, - IEnumId errorEndDtAfterStartDt, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorEndDtAfterStartDt, boolean required) { return new EndDtAfterStartDtRule<>(endDtFieldName, startDtFieldName, @@ -62,8 +62,8 @@ public record EndDtAfterStartDtRule( String startDtFieldName, Function getterEndDt, Function getterStartDt, - IEnumId errorEmptyRequiredValue, - IEnumId errorEndDtAfterStartDt) { + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorEndDtAfterStartDt) { return new EndDtAfterStartDtRule<>(endDtFieldName, startDtFieldName, getterEndDt, diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java index 13a3494ff..5b503aedf 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java @@ -2,8 +2,8 @@ package ru.spcex.clearing.validation.common.rules; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; @@ -18,8 +18,8 @@ public record EnumPresentRule(String fieldName, Function getter, E[] enumValues, boolean required, - IEnumId errorWrongEnumValue, - IEnumId errorEmptyRequiredValue) implements IValidationRule> { + IErrorEnumId errorWrongEnumValue, + IErrorEnumId errorEmptyRequiredValue) implements IValidationRule> { /** * @param fieldName Название поля @@ -35,8 +35,8 @@ public record EnumPresentRule(String fieldName, Function getter, E[] enumValues, boolean required, - IEnumId errorWrongEnumValue, - IEnumId errorEmptyRequiredValue) { + IErrorEnumId errorWrongEnumValue, + IErrorEnumId errorEmptyRequiredValue) { if (errorWrongEnumValue == null) throw new IllegalArgumentException("Empty errorWrongEnumValue"); if (required && errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); return new EnumPresentRule<>(fieldName, getter, enumValues, required, errorWrongEnumValue, errorEmptyRequiredValue); @@ -54,8 +54,8 @@ public record EnumPresentRule(String fieldName, public static EnumPresentRule instance(String fieldName, Function getter, E[] enumValues, - IEnumId errorWrongEnumValue, - IEnumId errorEmptyRequiredValue) { + IErrorEnumId errorWrongEnumValue, + IErrorEnumId errorEmptyRequiredValue) { return new EnumPresentRule<>(fieldName, getter, enumValues, true, errorWrongEnumValue, errorEmptyRequiredValue); } diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index 2e215648e..370f0147d 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -3,7 +3,7 @@ package ru.spcex.clearing.validation.common.rules; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; @@ -18,7 +18,7 @@ import java.util.function.Function; public record FieldRequiredRule( String fieldName, Function getter, - IEnumId errorEmptyRequiredValue + IErrorEnumId errorEmptyRequiredValue ) implements IValidationRule> { /** @@ -28,7 +28,7 @@ public record FieldRequiredRule( * @param Класс проверяемого объекта * @param Класс проверяемого значения */ - public static FieldRequiredRule instance(String fieldName, Function getter, IEnumId errorEmptyRequiredValue) { + public static FieldRequiredRule instance(String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue) { if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue); } diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java index 5ce3c570f..1c6abcfaf 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java @@ -4,7 +4,7 @@ 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.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; @@ -20,10 +20,10 @@ public record IdPresentRule( Function idGetter, String mapName, Class mapClass, - IEnumId errorEmptyRequiredValue, - IEnumId errorIdNotPresent, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorIdNotPresent, boolean required, - Function[] additionalChecks + Function[] additionalChecks ) implements IValidationRule> { /** @@ -43,10 +43,10 @@ public record IdPresentRule( Function idGetter, String mapName, Class mapClass, - IEnumId errorEmptyRequiredValue, - IEnumId errorIdNotPresent, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorIdNotPresent, boolean required, - Function ... additionalChecks) { + Function ... additionalChecks) { return new IdPresentRule<>(fieldName, idGetter, mapName, @@ -73,9 +73,9 @@ public record IdPresentRule( Function idGetter, String mapName, Class mapClass, - IEnumId errorEmptyRequiredValue, - IEnumId errorIdNotPresent, - Function ... additionalChecks) { + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorIdNotPresent, + Function ... additionalChecks) { return new IdPresentRule<>(fieldName, idGetter, mapName, @@ -96,8 +96,8 @@ public record IdPresentRule( if (fromMap == null) { return of(errorIdNotPresent, fieldName); } - for (Function additionalCheck : additionalChecks) { - IEnumId validationError = additionalCheck.apply(fromMap); + for (Function additionalCheck : additionalChecks) { + IErrorEnumId validationError = additionalCheck.apply(fromMap); if (validationError != null) return of(validationError, fieldName); } diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java index 3386c66cf..7ab42a96c 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java @@ -2,7 +2,7 @@ package ru.spcex.clearing.validation.common.rules; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.time.LocalTime; @@ -16,8 +16,8 @@ import java.util.function.Function; public record TimeNotBeforeRule( String fieldName, Function getter, - IEnumId errorEmptyRequiredValue, - IEnumId errorTaskForPastTime, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastTime, boolean required ) implements IValidationRule> { @@ -31,8 +31,8 @@ public record TimeNotBeforeRule( */ public static TimeNotBeforeRule instance(String fieldName, Function getter, - IEnumId errorEmptyRequiredValue, - IEnumId errorTaskForPastTime, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastTime, boolean required) { return new TimeNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastTime, required); } @@ -46,8 +46,8 @@ public record TimeNotBeforeRule( */ public static TimeNotBeforeRule instance(String fieldName, Function getter, - IEnumId errorEmptyRequiredValue, - IEnumId errorTaskForPastTime) { + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastTime) { return new TimeNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastTime, true); } 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 ca3edbd16..dea10bcdc 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 @@ -1,8 +1,8 @@ package ru.spcex.clearing.company.error; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum CompanyErrors implements IEnumId { +public enum CompanyErrors implements IErrorEnumId { GeneralError(3000L), // Общая ошибка модуля company-service UserVerifyDenial(3001L), // 'Нет прав на проведение данной операции diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java index ea04bfa3a..678f62c27 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/error/ValidationError.java @@ -1,8 +1,8 @@ package ru.spcex.clearing.scheduler.error; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum ValidationError implements IEnumId { +public enum ValidationError implements IErrorEnumId { WrongDictionaryValue(10003L), EmptyRequiredValue(10002L), WrongEnumValue(777L), //todo set code diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java index f43b0868e..0981c30ff 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java @@ -1,8 +1,8 @@ package ru.spcex.clearing.securities.errors; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum SecuritiesError implements IEnumId { +public enum SecuritiesError implements IErrorEnumId { RequiredFieldIsEmpty(1002L), WrongFieldValue(1004L), InstrumentAlreadyExists(1010L), diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java index 21b30f3af..0c55dc5f0 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java @@ -5,16 +5,16 @@ import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.Stored; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; public class IsValidInstrumentTypeById implements IValidationRule> { - private final IEnumId errorEnum; + private final IErrorEnumId errorEnum; private final String predictableInstrumentType; - public IsValidInstrumentTypeById(IEnumId errorEnum, String predictableInstrumentType) { + public IsValidInstrumentTypeById(IErrorEnumId errorEnum, String predictableInstrumentType) { this.errorEnum = errorEnum; this.predictableInstrumentType = predictableInstrumentType; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java index 68b8bb857..a051e0916 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java @@ -4,16 +4,16 @@ import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; public class IsValidInstrumentTypeFromRequest implements IValidationRule> { - private final IEnumId errorEnum; + private final IErrorEnumId errorEnum; private final String predictableInstrumentType; - public IsValidInstrumentTypeFromRequest(IEnumId errorEnum, String predictableInstrumentType) { + public IsValidInstrumentTypeFromRequest(IErrorEnumId errorEnum, String predictableInstrumentType) { this.errorEnum = errorEnum; this.predictableInstrumentType = predictableInstrumentType; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/NotPresentBySecuritySymbolAndWorkflowStatusActv.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/NotPresentBySecuritySymbolAndWorkflowStatusActv.java index c8ff2f025..a65516a81 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/NotPresentBySecuritySymbolAndWorkflowStatusActv.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/NotPresentBySecuritySymbolAndWorkflowStatusActv.java @@ -8,7 +8,7 @@ import ru.spcex.platform.enumeration.Status; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Map; @@ -16,10 +16,10 @@ import java.util.Optional; public class NotPresentBySecuritySymbolAndWorkflowStatusActv implements IValidationRule> { private final String mapName; - private final IEnumId errorEnum; + private final IErrorEnumId errorEnum; private final Class clazz; - public NotPresentBySecuritySymbolAndWorkflowStatusActv(String mapName, IEnumId errorEnum, Class clazz) { + public NotPresentBySecuritySymbolAndWorkflowStatusActv(String mapName, IErrorEnumId errorEnum, Class clazz) { this.mapName = mapName; this.errorEnum = errorEnum; this.clazz = clazz; diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java index 824f0acea..1da49900d 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/validation/rule/PresentById.java @@ -5,21 +5,21 @@ import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.Stored; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; public class PresentById implements IValidationRule> { private final String mapName; - private final IEnumId errorEnum; + private final IErrorEnumId errorEnum; private boolean storeEnabled = false; - public PresentById(String mapName, IEnumId errorEnum) { + public PresentById(String mapName, IErrorEnumId errorEnum) { this.mapName = mapName; this.errorEnum = errorEnum; } - public PresentById(String mapName, IEnumId errorEnum, Boolean storeEnabled) { + public PresentById(String mapName, IErrorEnumId errorEnum, Boolean storeEnabled) { this.mapName = mapName; this.errorEnum = errorEnum; this.storeEnabled = storeEnabled; diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/enumeration/IErrorEnumId.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/enumeration/IErrorEnumId.java new file mode 100644 index 000000000..e527b2645 --- /dev/null +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/enumeration/IErrorEnumId.java @@ -0,0 +1,5 @@ +package ru.spcex.platform.utils.enumeration; + + +public interface IErrorEnumId extends IEnumId { +} diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java index 3ad88a3f1..d5a3f8be7 100644 --- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidationRule.java @@ -1,7 +1,7 @@ package ru.spcex.platform.utils.validation; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import java.util.Optional; @@ -29,11 +29,11 @@ public interface IValidationRule { } //*************** методы для сокращения кода *************** - default Optional of(IEnumId error) { + default Optional of(IErrorEnumId error) { return Optional.of(new EnumMessage(error)); } - default Optional of(IEnumId error, Object... args) { + default Optional of(IErrorEnumId error, Object... args) { return Optional.of(new EnumMessage(error, args)); } diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestEnumWithId.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestEnumWithId.java index f357d0c12..de4291d02 100644 --- a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestEnumWithId.java +++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestEnumWithId.java @@ -1,8 +1,9 @@ package ru.spcex.platform.utils.validation; import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; -public enum TestEnumWithId implements IEnumId { +public enum TestEnumWithId implements IEnumId, IErrorEnumId { Message1(1L), Message2(2L), Message3(3L), From 4ffbefbbe078ae41447c6191bf0bd6abee023b1f Mon Sep 17 00:00:00 2001 From: AKurakin Date: Tue, 4 Apr 2023 21:50:31 +0300 Subject: [PATCH 31/90] =?UTF-8?q?CLS-256,=20CLS-259=20=D0=BD=D0=B5=D0=BC?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=BB=D0=BE=D1=81=D1=8C=20API=20=D0=BF=D0=BE=20meta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../queue/company/CompanyController.java | 11 +++++ .../request/cud/company/CompanyNewAction.java | 44 ++++++++++--------- .../company/service/CompanyService.java | 3 -- .../domain/cud/company/CompanyNewRequest.java | 32 -------------- 4 files changed, 34 insertions(+), 56 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java index f75928320..90a040de1 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java @@ -67,4 +67,15 @@ public class CompanyController extends AbstractQueueController { @RequestBody CompanyNewAction companyNewAction) throws ExecutionException, InterruptedException { return processRequest(Consts.DESTINATION_COMPANY_NEW, companyNewAction); } + + +// @ApiOperation(value = "update company.") +// @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) +// @RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) +// @ResponseBody +// public CudResponse add( +// @ApiParam(value = "Параметры команды в JSON формате.", required = true) +// @RequestBody CompanyNewAction companyNewAction) throws ExecutionException, InterruptedException { +// return processRequest(Consts.DESTINATION_COMPANY_NEW, companyNewAction); +// } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java index b44582218..675046e44 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java @@ -14,24 +14,26 @@ public class CompanyNewAction implements IAction { @ApiModelProperty(value = "Полное наименование Компании", example = "OOO Full Company Name") @JsonProperty private String fullName; - @ApiModelProperty(value = "Код участника торгов", example = "TRADINGCODE") + + @ApiModelProperty(value = "Тип реквизита", example = "TRDC") @JsonProperty - private String tradingCode; - @ApiModelProperty(value = "Код участника клиринга", example = "CLEARINGCODE") + private String companySymbol; + @ApiModelProperty(value = "Значение реквизита", example = "COMPANYSYMBOL_VALUE-123") @JsonProperty - private String clearingCode; - @ApiModelProperty(value = "Регистрационный код участника", example = "REGISTRATIONCODE") + private String companySymbolValue; + @ApiModelProperty(value = "Наименование статуса", example = "ACTV") @JsonProperty - private String registrationCode; + private String workflowStatus; + @Override public CompanyNewRequest toRequest() { CompanyNewRequest request = new CompanyNewRequest(); request.setShortName(this.shortName); request.setFullName(this.fullName); - request.setTradingCode(this.tradingCode); - request.setClearingCode(this.clearingCode); - request.setRegistrationCode(this.registrationCode); + request.setCompanySymbol(this.companySymbol); + request.setCompanySymbolValue(this.companySymbolValue); + request.setWorkflowStatus(this.workflowStatus); return request; } @@ -57,27 +59,27 @@ public class CompanyNewAction implements IAction { this.fullName = fullName; } - public String getTradingCode() { - return tradingCode; + public String getCompanySymbol() { + return companySymbol; } - public void setTradingCode(String tradingCode) { - this.tradingCode = tradingCode; + public void setCompanySymbol(String companySymbol) { + this.companySymbol = companySymbol; } - public String getClearingCode() { - return clearingCode; + public String getCompanySymbolValue() { + return companySymbolValue; } - public void setClearingCode(String clearingCode) { - this.clearingCode = clearingCode; + public void setCompanySymbolValue(String companySymbolValue) { + this.companySymbolValue = companySymbolValue; } - public String getRegistrationCode() { - return registrationCode; + public String getWorkflowStatus() { + return workflowStatus; } - public void setRegistrationCode(String registrationCode) { - this.registrationCode = registrationCode; + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; } } 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 69af48acd..c6f80e00e 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 @@ -52,9 +52,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private Function companyUpdateRequestValidator; private Function companyDeleteRequestValidator; - // Синхронизация обновлений - public final Object lockCompany = new Object(); // Company, CompanySymbol, - @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java index 79685bd20..87476c8e6 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java @@ -15,14 +15,6 @@ public class CompanyNewRequest { @JsonProperty private String workflowStatus; - //todo deprecated 3 field: - @JsonProperty - private String tradingCode; - @JsonProperty - private String clearingCode; - @JsonProperty - private String registrationCode; - // for update, todo разобраться, это тот же тип запроса или надо отдельный на update сделать? @JsonProperty private Long id; @@ -43,30 +35,6 @@ public class CompanyNewRequest { this.fullName = fullName; } - 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 getCompanySymbol() { return companySymbol; } From 7ff3de272424703fbc2f2e8ee7a222dee252174c Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 09:36:56 +0300 Subject: [PATCH 32/90] =?UTF-8?q?CLS-259=20util=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=B0=D1=81=D1=81=D0=B8=D0=BD=D1=85=D1=80?= =?UTF-8?q?=D0=BE=D0=BD=D0=BD=D0=BE-=D1=81=D0=B8=D0=BD=D1=85=D1=80=D0=BE?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=BE=D0=B1=D0=BC=D0=B5=D0=BD=20?= =?UTF-8?q?=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D1=8F=D0=BC?= =?UTF-8?q?=D0=B8=20(=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9?= =?UTF-8?q?=D1=81)=20BiDirectionQueueExchanger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exchangers/BiDirectionQueueExchanger.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java new file mode 100644 index 000000000..0f08fe624 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java @@ -0,0 +1,66 @@ +package ru.spcex.clearing.util.services.exchangers; + +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.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; + +/** + * Синхронный обмен сообщениями с ассинхронным сервисом. + * Метод exchange() отправляет сообщение в очередь и дожидается ответа из другой очереди + */ +public class BiDirectionQueueExchanger> extends QueueConsumer implements InitializingBean, DisposableBean { + 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; + + /** + * Синхронно-ассинхронный обмен сообщениями + * + * @param kafkaQueue + * @param kafkaProducer + * @param outQueue отправляет в очередь + * @param inQueue слушает очередь, ожидает ответов + * @param listenClass типы объектов из inQueue + * @param timeout - максимальное ожидание ответа, в миллисекундах, 0 - неограничено + */ + public BiDirectionQueueExchanger(Consumer kafkaQueue, Producer kafkaProducer, + String outQueue, + String inQueue, Class listenClass, + long timeout) { + super(kafkaQueue, kafkaProducer); + this.outQueue = outQueue; + this.inQueue = inQueue; + this.listenClass = listenClass; + this.timeout = timeout; + } + + /** + * Отправить сообщение message в outQueue и дождаться ответа из очереди inQueue + * + * @param message + * @return + * @throws InterruptedException + */ + public TOut exchange(TIn message) throws InterruptedException { + //todo impl BiDirectionQueueExchanger + return null; + } + + @Override + public void destroy() throws Exception { + log.debug("Listener {} for async exchange {}-{} close", this, outQueue, inQueue); + } + + @Override + public void afterPropertiesSet() throws Exception { + log.debug("Listener {} for async exchange {}-{} ready", this, outQueue, inQueue); + } +} From 7fea5d46cda5abffc11dedadad1597452724fc99 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 5 Apr 2023 11:26:00 +0300 Subject: [PATCH 33/90] ContactUpdateRequest and meta.xml fix --- .../backend-api/src/main/resources/meta/meta.xml | 5 +++++ .../domain/cud/company/ContactUpdateRequest.java | 11 ----------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index 640e1b1ef..c58b7e55a 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -385,6 +385,11 @@ + + + + + diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactUpdateRequest.java index 92e4f11db..f03a0833d 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/ContactUpdateRequest.java @@ -5,9 +5,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class ContactUpdateRequest { @JsonProperty public Long id; - - @JsonProperty - private Long companyId; @JsonProperty private String contactType; @JsonProperty @@ -21,14 +18,6 @@ public class ContactUpdateRequest { this.id = id; } - public Long getCompanyId() { - return companyId; - } - - public void setCompanyId(Long companyId) { - this.companyId = companyId; - } - public String getContactType() { return contactType; } From ddc27dbb33bd79eb0ddb30b5a3d7e0e8b3873d24 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 5 Apr 2023 11:30:41 +0300 Subject: [PATCH 34/90] ContactUpdateRequest and meta.xml fix --- clearing-parent/backend-api/src/main/resources/meta/meta.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index c58b7e55a..7f4155354 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -385,11 +385,11 @@ - + - + From 30d600cdc87cc8ae9ec883264460ed2c559d2352 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 5 Apr 2023 11:52:21 +0300 Subject: [PATCH 35/90] ContactTypes enum added --- .../platform/enumeration/ContactTypes.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ContactTypes.java diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ContactTypes.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ContactTypes.java new file mode 100644 index 000000000..700babd7d --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ContactTypes.java @@ -0,0 +1,31 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +/** + * CONTACT_TYPE_DICTIONARY + */ +public enum ContactTypes implements IEnumKey { + adrs("ADRS"), // Адрес + post("POST"), // Почтовый адрес + cont("CONT"), // Контактное лицо + mail("MAIL"), // Электронная почта + phon("PHON"), // Телефон + gdir("GDIR"), // Генеральный директор + trst("TRST"), // Доверенное лицо + fax("FAX"), // Факс + info("INFO"), // Контактная информация + cmnt("CMNT"); // Примечание + + + private final String key; + + ContactTypes(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +} From 3140ea911ee7602551d7d56b29e7cdf244c5ae59 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 12:31:50 +0300 Subject: [PATCH 36/90] backend-api: ContactUpdateRequest and meta.xml fix --- .../request/cud/company/ContactUpdateAction.java | 12 ------------ .../queue/company/EditContactControllerTest.java | 2 -- 2 files changed, 14 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/ContactUpdateAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/ContactUpdateAction.java index f542eac1b..c40659ad9 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/ContactUpdateAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/ContactUpdateAction.java @@ -11,9 +11,6 @@ public class ContactUpdateAction implements IAction { @JsonProperty public Long id; - @ApiModelProperty(value = "Идентификатор Компании", example = "1234") - @JsonProperty - private Long companyId; @ApiModelProperty(value = "Идентификатор справочника", example = "ABCD") @JsonProperty private String contactType; @@ -25,7 +22,6 @@ public class ContactUpdateAction implements IAction { public ContactUpdateRequest toRequest() { ContactUpdateRequest request = new ContactUpdateRequest(); request.setId(this.id); - request.setCompanyId(this.companyId); request.setContactType(this.contactType); request.setContactValue(this.contactValue); return request; @@ -45,14 +41,6 @@ public class ContactUpdateAction implements IAction { this.id = id; } - public Long getCompanyId() { - return companyId; - } - - public void setCompanyId(Long companyId) { - this.companyId = companyId; - } - public String getContactType() { return contactType; } diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java index 5f51b0b1c..3f256dc8f 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java @@ -39,7 +39,6 @@ class EditContactControllerTest extends AbstractControllerTest { * {@link EditContactController#update(Long, ContactUpdateAction)}
* Тест проверяет получение сущности {@link ContactUpdateAction} по REST API и отправку в Apache Kafka.
* Входной запрос {@link ContactUpdateAction}:
- * {@link ContactUpdateAction#companyId} - 1000L
* {@link ContactUpdateAction#contactType} - ContactType
* {@link ContactUpdateAction#contactValue} - ContactValue
* {@link ContactUpdateAction#id} - currentId
@@ -48,7 +47,6 @@ class EditContactControllerTest extends AbstractControllerTest { void update() throws Exception { //ARRANGE ContactUpdateAction companySymbolUpdateAction = new ContactUpdateAction(); - companySymbolUpdateAction.setCompanyId(1000L); companySymbolUpdateAction.setContactType("ContactType"); companySymbolUpdateAction.setContactValue("ContactValue"); companySymbolUpdateAction.setId(currentId.get()); From 9aeb6ca6ee931be705e2cdda861d96039e8e0cad Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 12:33:20 +0300 Subject: [PATCH 37/90] =?UTF-8?q?backend-api,=20UserMapStore:=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20BaseRe?= =?UTF-8?q?quest.userId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backendapi/service/impl/OperatorImpl.java | 26 +++++++++++++++++++ .../imdg/businessobject/UserMapStore.java | 6 ++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java index 1f21495fd..c3dbe2c7d 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java @@ -1,14 +1,21 @@ package ru.spcex.clearing.backendapi.service.impl; +import org.apache.commons.lang3.StringUtils; 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.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.user.User; import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse; import ru.spcex.clearing.backendapi.domain.actions.IAction; import ru.spcex.clearing.backendapi.errors.ActionValidationException; import ru.spcex.clearing.backendapi.errors.BackEndError; import ru.spcex.clearing.backendapi.errors.NotFound404Exception; +import ru.spcex.clearing.backendapi.security.KeycloakUtils; import ru.spcex.clearing.backendapi.service.IOperator; import ru.spcex.clearing.backendapi.service.validation.ActionValidationProvider; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -21,21 +28,39 @@ import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.validation.IValidator; import java.util.Collection; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @Service public class OperatorImpl implements IOperator { + protected final Logger log = LoggerFactory.getLogger(getClass()); private final Producer kafka; private final ImdgId idGenerator; private final ImdgProvider imdgProvider; private final ActionValidationProvider validation; + private final Imdg userImdg; public OperatorImpl(Producer kafka, ImdgProvider imdgProvider, ActionValidationProvider validation) { this.kafka = kafka; this.idGenerator = imdgProvider.getImdgIdGenerator(); this.imdgProvider = imdgProvider; this.validation = validation; + this.userImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_User, User.class); + } + + + protected Long currentUserId() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String username = KeycloakUtils.getUserNameFromAuthentication(authentication); + User user = StringUtils.isEmpty(username) ? null : userImdg.getSingleObjectByFieldValues(Map.of("identifier", username)); + if (user == null) { + log.warn("UserID not found by login \"{}\"", username); + return null; + //throw new IllegalStateException("cannot obtain userId from logged in user " + username); + } + return user.getId(); + // todo добавить кэш, с очисткой по времени } @Override @@ -45,6 +70,7 @@ public class OperatorImpl implements IOperator { request.setId(idGenerator.nextId()); request.setActionType(iAction.getActionType()); request.setRequestPayload(iAction.toRequest()); + request.setUserId(currentUserId()); //сохраняет данные о запросе в хранилище saveRequestToStorage(destination, request); Future send = kafka.send(new ProducerRecord<>(destination, request)); diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/UserMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/UserMapStore.java index c63197d6f..e2cc7ba57 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/UserMapStore.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/businessobject/UserMapStore.java @@ -30,10 +30,14 @@ public class UserMapStore extends TemplateMapStore { @Override public String[] getFields() { return new String[]{ - "ID", "CREATED_AT", "UPDATED_AT", "IDENTIFIER", "NAME", "FIRST_NAME", "LAST_NAME", "MIDDLE_NAME", "EMAIL", + "ID", "CREATED_AT", "UPDATED_AT", "IDENTIFIER", "NAME", "FIRST_NAME", "LAST_NAME", "MIDDLE_NAME", "EMAIL", }; } + public String[] getIndexingField() { + return new String[]{"identifier"}; + } + @Override public User objectReader(ResultSet resultSet) throws SQLException { User object = new User(); From 1e5e4e393dc978b945469354aafdb681bfcaa80b Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 12:33:37 +0300 Subject: [PATCH 38/90] backend-api . --- .../controller/queue/company/CompanyController.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java index 90a040de1..f75928320 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyController.java @@ -67,15 +67,4 @@ public class CompanyController extends AbstractQueueController { @RequestBody CompanyNewAction companyNewAction) throws ExecutionException, InterruptedException { return processRequest(Consts.DESTINATION_COMPANY_NEW, companyNewAction); } - - -// @ApiOperation(value = "update company.") -// @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) -// @RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) -// @ResponseBody -// public CudResponse add( -// @ApiParam(value = "Параметры команды в JSON формате.", required = true) -// @RequestBody CompanyNewAction companyNewAction) throws ExecutionException, InterruptedException { -// return processRequest(Consts.DESTINATION_COMPANY_NEW, companyNewAction); -// } } From 316e2fe042da9bdf477025401b4d228aab427fe9 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 13:18:59 +0300 Subject: [PATCH 39/90] =?UTF-8?q?backend-api,=20UserMapStore:=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20BaseRe?= =?UTF-8?q?quest.userId=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/queue/AbstractQueueController.java | 2 +- .../ru/spcex/clearing/backendapi/service/IOperator.java | 2 +- .../clearing/backendapi/service/UserAuthProcessor.java | 4 ++-- .../clearing/backendapi/service/impl/OperatorImpl.java | 6 ++++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/AbstractQueueController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/AbstractQueueController.java index 6aa77ebba..5718d77e3 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/AbstractQueueController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/AbstractQueueController.java @@ -15,7 +15,7 @@ public class AbstractQueueController { protected CudResponse processRequest(String destination, IAction iAction) throws ExecutionException, InterruptedException { CudResponse responseToClient = new CudResponse(); - responseToClient.setPayload(operator.sendRequestToQueue(destination, iAction)); + responseToClient.setPayload(operator.sendRequestToQueue(destination, iAction, true)); responseToClient.setCode(0); responseToClient.setMessage("success"); return responseToClient; diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/IOperator.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/IOperator.java index 6d86d7660..67c331b7a 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/IOperator.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/IOperator.java @@ -6,5 +6,5 @@ import ru.spcex.clearing.backendapi.domain.actions.IAction; import java.util.concurrent.ExecutionException; public interface IOperator { - QueueSuccessResponse sendRequestToQueue(String destination, IAction iAction) throws ExecutionException, InterruptedException; + QueueSuccessResponse sendRequestToQueue(String destination, IAction iAction, boolean appendUserId) throws ExecutionException, InterruptedException; } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java index a98799a8a..ba9789792 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java @@ -47,7 +47,7 @@ public class UserAuthProcessor { requestData.setSurname(surname); requestData.setMiddleName(middleName); try { - operator.sendRequestToQueue(Consts.USER_AUTH_SUCCESS, authEvent); + operator.sendRequestToQueue(Consts.USER_AUTH_SUCCESS, authEvent, false); } catch (Throwable e) { //ExecutionException | InterruptedException log.error(ExceptionUtils.getStackTrace(e)); } @@ -59,7 +59,7 @@ public class UserAuthProcessor { requestData.setUsername(identifier); requestData.setTime(Instant.now()); try { - operator.sendRequestToQueue(Consts.USER_LOGOUT_SUCCESS, logoutEvent); + operator.sendRequestToQueue(Consts.USER_LOGOUT_SUCCESS, logoutEvent, false); } catch (Throwable e) { log.error(ExceptionUtils.getStackTrace(e)); } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java index c3dbe2c7d..b039cdd82 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/impl/OperatorImpl.java @@ -64,13 +64,15 @@ public class OperatorImpl implements IOperator { } @Override - public QueueSuccessResponse sendRequestToQueue(String destination, IAction iAction) throws ExecutionException, InterruptedException { + public QueueSuccessResponse sendRequestToQueue(String destination, IAction iAction, boolean appendUserId) throws ExecutionException, InterruptedException { throwValidate(destination, iAction); BaseRequest request = new BaseRequest<>(); request.setId(idGenerator.nextId()); request.setActionType(iAction.getActionType()); request.setRequestPayload(iAction.toRequest()); - request.setUserId(currentUserId()); + if (appendUserId) { + request.setUserId(currentUserId()); + } //сохраняет данные о запросе в хранилище saveRequestToStorage(destination, request); Future send = kafka.send(new ProducerRecord<>(destination, request)); From c8306a1f7f123ccee7ff9f8a6e650a4e7e43843b Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 13:23:52 +0300 Subject: [PATCH 40/90] Imdg.insert return id --- .../platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java | 3 ++- .../imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java | 3 ++- .../src/main/java/ru/spcex/platform/imdg/api/Imdg.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java index c447524f6..c30a3c9d0 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java @@ -40,11 +40,12 @@ public class ImdgHazelcast implements Imdg { } @Override - public void insert(T paramT) { + public Long insert(T paramT) { if (paramT.getId() == null) { paramT.setId(idGenerator.newId()); } map.put(paramT.getId(), paramT); + return paramT.getId(); } @Override diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java index f58ef3c8b..8a241c6af 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java @@ -25,11 +25,12 @@ public class ImdgTransactionalHazelcast implements Im private HazelcastInstance hzInstance; @Override - public void insert(T paramT) { + public Long insert(T paramT) { if (paramT.getId() == null) { paramT.setId(idGenerator.newId()); } map.put(paramT.getId(), paramT); + return paramT.getId(); } @Override diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java index bc4adb9c1..8002b554b 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java @@ -12,7 +12,7 @@ public interface Imdg { throw new UnsupportedOperationException("not implemented name"); } - default void insert(T paramT) { + default Long insert(T paramT) { throw new UnsupportedOperationException("not implemented insert"); } From 64e0dbbcf3f527f7694c370274e689b9f69b3975 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 13:30:18 +0300 Subject: [PATCH 41/90] =?UTF-8?q?backend-api,=20UserMapStore:=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20BaseRe?= =?UTF-8?q?quest.userId=20fix=20unittest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/spcex/clearing/backendapi/security/KeycloakUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakUtils.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakUtils.java index 52bc02e40..a4e60ac57 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakUtils.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakUtils.java @@ -11,6 +11,7 @@ public class KeycloakUtils { */ public static String getUserNameFromAuthentication(Authentication authentication) { KeycloakAuthenticationToken auth = (KeycloakAuthenticationToken) authentication; + if (auth == null) return null; KeycloakAccount details = (KeycloakAccount) auth.getDetails(); return ((KeycloakPrincipal) details.getPrincipal()) .getKeycloakSecurityContext() From 6ea7520b7b2c75d1cab7146e868980ac6c644bd6 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 5 Apr 2023 13:50:40 +0300 Subject: [PATCH 42/90] new CompanyErrors added --- clearing-parent/backend-api/src/main/resources/meta/data.xml | 2 ++ .../java/ru/spcex/clearing/company/error/CompanyErrors.java | 3 ++- clearing-parent/db-scripts/src/main/resources/db/DATA.sql | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) 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 cd25509ed..bbb275fc9 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/data.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/data.xml @@ -245,6 +245,8 @@ + + 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 dea10bcdc..84cba81e5 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 @@ -20,7 +20,8 @@ public enum CompanyErrors implements IErrorEnumId { CategoryNotFound(3016L), // Категория компании %s не найдена. CategoryAlreadySet(3017L), // Компании %s уже присвоена категория %s. CompanyAlreadyHas_(3018L), // У компании %s присутствуют обязательства. - + EditCompanySymbols(3020L), // Тип реквизита компании %s не может быть изменен. + EditContactType(3021L) // Тип контакта компании %s не может быть изменен. ; private final Long id; 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 29a1b2181..51d2c5f8b 100644 --- a/clearing-parent/db-scripts/src/main/resources/db/DATA.sql +++ b/clearing-parent/db-scripts/src/main/resources/db/DATA.sql @@ -476,6 +476,10 @@ INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (3017, 'CMPN', 'Ком INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (3018, 'CMPN', 'У компании %s присутствуют обязательства.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (3020, 'CMPN', 'Тип реквизита компании %s не может быть изменен.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (3021, 'CMPN', 'Тип контакта компании %s не может быть изменен.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (4000, 'RPRT', 'Общая ошибка модуля report-serivce.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (5000, 'ACNT', 'Общая ошибка модуля account-service.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; From 2f01256a6672e4e584acbbd1a46c4a0b3df68014 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 5 Apr 2023 14:18:28 +0300 Subject: [PATCH 43/90] ContactService validation --- .../validation/ContactValidationConfig.java | 106 ++++++++++++++++++ .../config/validation/ValidationConfig.java | 4 + .../company/service/ContactService.java | 56 ++++++++- .../ClearingMemberCategoryServiceTest.java | 5 +- .../company/service/ContactServiceTest.java | 79 ++++++++++--- .../service/ProfileDocumentServiceTest.java | 5 +- 6 files changed, 230 insertions(+), 25 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java 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 new file mode 100644 index 000000000..3cb98b376 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java @@ -0,0 +1,106 @@ +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.profile.Contact; +import ru.clearing.platform.dictionary.ContactTypeDictionary; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactUpdateRequest; +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.ContactTypes; +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 ContactValidationConfig { + + @Bean("contactNewRequestValidator") + public Function contactNewRequestValidator( + Map> imdgForValidation + ) { + return contactNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(contactNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_ContactTypeDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + ContactNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound), + EnumPresentRule.instance("contactType", + ContactNewRequest::getContactType, + ContactTypes.values(), + CompanyErrors.WrongFieldValue, + CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("contactType", + ContactNewRequest::getContactType, + IMDGDistributedNames.Map_ContactTypeDictionary, + ContactTypeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue), + FieldRequiredRule.instance("contactValue", + ContactNewRequest::getContactValue, + CompanyErrors.RequiredFieldEmpty) + ); + }; + } + + @Bean("contactUpdateRequestValidator") + public Function contactUpdateRequestValidator( + Map> imdgForValidation + ) { + return contactUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(contactUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Contact); + addImdg.accept(IMDGDistributedNames.Map_ContactTypeDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + ContactUpdateRequest::getId, + IMDGDistributedNames.Map_Contact, + Contact.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound, + contact -> { + if (contactUpdateRequest.getContactType() == null) return null; + if (!contactUpdateRequest.getContactType().equalsIgnoreCase(contact.getContactType())) { + return CompanyErrors.EditContactType; + } + return null; + }), + EnumPresentRule.instance("contactType", + ContactUpdateRequest::getContactType, + ContactTypes.values(), + false, + CompanyErrors.WrongFieldValue, + CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("contactType", + ContactUpdateRequest::getContactType, + IMDGDistributedNames.Map_ContactTypeDictionary, + ContactTypeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false) + ); + }; + } + +} 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 20ce51e01..06c9aadc6 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 @@ -4,8 +4,10 @@ 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.generated.ClearingMemberCategory; +import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.platform.dictionary.ContactTypeDictionary; import ru.clearing.platform.dictionary.DocumentTypeDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; @@ -31,6 +33,8 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary, ClearingCategoryDictionary.class); addImdg.accept(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); 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_WorkflowStatusDictionary, DocumentTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java index 44940401c..814902983 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java @@ -6,44 +6,90 @@ 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.profile.Contact; 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.company.ContactNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactUpdateRequest; 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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.validation.IValidator; + +import java.util.function.Function; @Service public class ContactService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg contactMap; + private final ValidationHelper validationHelper; + private final Function contactNewRequestValidator; + private final Function contactUpdateRequestValidator; @Autowired - public ContactService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider) { + public ContactService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationHelper validationHelper, + @Qualifier("contactNewRequestValidator") Function contactNewRequestValidator, + @Qualifier("contactUpdateRequestValidator") Function contactUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); this.contactMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Contact, Contact.class); + this.validationHelper = validationHelper; + this.contactNewRequestValidator = contactNewRequestValidator; + this.contactUpdateRequestValidator = contactUpdateRequestValidator; } @Override public void afterPropertiesSet() { + callback(ContactNewRequest.class) + .setConsumer(this::contactNew) + .forDestination(Consts.DESTINATION_CONTACT_NEW, callbacks::put); callback(ContactUpdateRequest.class) .setConsumer(this::contactUpdate) .forDestination(Consts.DESTINATION_CONTACT_UPDATE, callbacks::put); init(); } - public void contactUpdate(BaseRequest userRequest) { - ContactUpdateRequest req = userRequest.getRequestPayload(); + public RequestInfoUpdate contactNew(BaseRequest userRequest) { + log.debug("ContactNewRequest received"); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( + userRequest, contactNewRequestValidator + ); + if (requestInfoUpdate != null) return requestInfoUpdate; + + ContactNewRequest contactNewRequest = userRequest.getRequestPayload(); + Contact contact = new Contact(); + contact.setCompanyId(contactNewRequest.getCompanyId()); + contact.setContactType(contactNewRequest.getContactType()); + contact.setContactValue(contactNewRequest.getContactValue()); + Long id = contactMap.insert(contact); + + log.debug("successfully processed, id {}", id); + return null; + } + + public RequestInfoUpdate contactUpdate(BaseRequest userRequest) { log.debug("ContactUpdateRequest received"); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( + userRequest, contactUpdateRequestValidator + ); + if (requestInfoUpdate != null) return requestInfoUpdate; + + // Тип контакта не меняем, при валидации кидаем ошибку. + ContactUpdateRequest req = userRequest.getRequestPayload(); Contact contact = contactMap.getSingleObjectByID(req.getId()); -// contact.setContactType(req.getContactType()); по ТЗ не должен менятся при обновлении contact.setContactValue(req.getContactValue()); contactMap.update(contact); log.debug("successfully processed, id {}", contact.getId()); + return null; } } \ No newline at end of file diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java index 25ae9344b..4d78b455d 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java @@ -67,7 +67,7 @@ class ClearingMemberCategoryServiceTest { @SpyBean private MockProducer mockProducer; - private final long COMPANY_ID = 777L; + private long COMPANY_ID; private Company TEST_COMPANY; private final String CLEARING_CATEGORY_DICT_CODE = ClearingCategory.B.getKey(); @@ -87,9 +87,8 @@ class ClearingMemberCategoryServiceTest { Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); TEST_COMPANY = new Company(); - TEST_COMPANY.setId(COMPANY_ID); TEST_COMPANY.setWorkflowStatus(WorkflowStatus.Active.getKey()); - companyImdg.insert(TEST_COMPANY); + COMPANY_ID = companyImdg.insert(TEST_COMPANY); clearingCategoryDictionary = new ClearingCategoryDictionary(); clearingCategoryDictionary.setCode(CLEARING_CATEGORY_DICT_CODE); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java index fe81faca4..e361852d5 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java @@ -12,14 +12,22 @@ 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.profile.Contact; +import ru.clearing.platform.dictionary.ContactTypeDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.ContactValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; 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.company.ContactNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactUpdateRequest; +import ru.spcex.platform.enumeration.ContactTypes; +import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @@ -30,6 +38,9 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, + ContactValidationConfig.class, ContactService.class, KafkaConfigTest.class, HazelcastServiceTestConfiguration.class}) @@ -38,6 +49,7 @@ class ContactServiceTest { public static final MatcherFactory.Matcher CONTACT_MATCHER = usingIgnoringFieldsComparator(); private static final int PARTITION = 0; private static final String TOPIC_CONTACT_UPDATE = Consts.DESTINATION_CONTACT_UPDATE; + private static final String TOPIC_CONTACT_NEW = Consts.DESTINATION_CONTACT_NEW; private static final Long ID = 0L; @Autowired @@ -53,10 +65,50 @@ class ContactServiceTest { @SpyBean private MockProducer mockProducer; + private Company TEST_COMPANY; + private Long COMPANY_ID; + @PostConstruct private void init() { hazelcastServiceTest.waitAvailable(); contactImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Contact, Contact.class); + + Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + TEST_COMPANY = new Company(); + TEST_COMPANY.setWorkflowStatus(WorkflowStatus.Active.getKey()); + COMPANY_ID = companyImdg.insert(TEST_COMPANY); + + ContactTypeDictionary contactTypeDictionary = new ContactTypeDictionary(); + contactTypeDictionary.setCode(ContactTypes.adrs.getKey()); + contactTypeDictionary.setName("name"); + Imdg contactTypeDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ContactTypeDictionary, ContactTypeDictionary.class + ); + contactTypeDictionaryImdg.insert(contactTypeDictionary); + } + @Test + void contactNew() throws InterruptedException { + //ARRANGE + ContactNewRequest contactNewRequest = new ContactNewRequest(); + contactNewRequest.setCompanyId(COMPANY_ID); + contactNewRequest.setContactType(ContactTypes.adrs.getKey()); + contactNewRequest.setContactValue("value"); + + Contact predictableContact = new Contact(); + predictableContact.setCompanyId(COMPANY_ID); + predictableContact.setContactType(ContactTypes.adrs.getKey()); + predictableContact.setContactValue("value"); + + //ACT + String jsonString = getJsonStringForNew(contactNewRequest, ID); + addRecordToKafka((MockConsumer) contactService.getConsumer(), TOPIC_CONTACT_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + Contact resultNew = contactImdg.getAllValues().iterator().next(); + predictableContact.setId(resultNew.getId()); + CONTACT_MATCHER.assertMatch(resultNew, predictableContact); } /** @@ -65,39 +117,38 @@ class ContactServiceTest { * Входной запрос {@link ContactUpdateRequest}:
* {@link ContactUpdateRequest#id} - Идентификатор записи
* {@link ContactUpdateRequest#companyId} - Идентификатор записи
- * {@link ContactUpdateRequest#contactType} - 1234
+ * {@link ContactUpdateRequest#contactType} - ADDR
* {@link ContactUpdateRequest#contactValue} - new ContactValue
*/ @Test void contactUpdate() throws InterruptedException { //ARRANGE + Long existContactID; Contact existsContact = new Contact(); - existsContact.setId(ID); - existsContact.setCompanyId(ID); - existsContact.setContactType("0000"); + existsContact.setCompanyId(COMPANY_ID); + existsContact.setContactType(ContactTypes.adrs.getKey()); existsContact.setContactValue("exists ContactValue"); - contactImdg.insert(existsContact); + existContactID = contactImdg.insert(existsContact); ContactUpdateRequest contactUpdateRequest = new ContactUpdateRequest(); - contactUpdateRequest.setId(ID); - contactUpdateRequest.setCompanyId(1L); - contactUpdateRequest.setContactType("1234"); + contactUpdateRequest.setId(existContactID); + contactUpdateRequest.setContactType(ContactTypes.adrs.getKey()); contactUpdateRequest.setContactValue("new ContactValue"); Contact predictableContact = new Contact(); - predictableContact.setId(ID); - predictableContact.setCompanyId(ID); - predictableContact.setContactType("0000"); + predictableContact.setId(existContactID); + predictableContact.setCompanyId(COMPANY_ID); + predictableContact.setContactType(ContactTypes.adrs.getKey()); predictableContact.setContactValue("new ContactValue"); //ACT - String jsonString = getJsonStringForUPDATE(contactUpdateRequest, ID); + String jsonString = getJsonStringForUPDATE(contactUpdateRequest, existContactID); addRecordToKafka((MockConsumer) contactService.getConsumer(), TOPIC_CONTACT_UPDATE, PARTITION, 0, jsonString); //ASSERT - waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + waitingWhenAddedRecordAndCheckIt(existContactID, mockProducer, producerRecord); - Contact resultUpdating = contactImdg.getSingleObjectByID(ID); + Contact resultUpdating = contactImdg.getSingleObjectByID(existContactID); CONTACT_MATCHER.assertMatch(resultUpdating, predictableContact); } } \ No newline at end of file diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java index c2ed53986..298d1483d 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java @@ -68,7 +68,7 @@ class ProfileDocumentServiceTest { @SpyBean private MockProducer mockProducer; - private final long COMPANY_ID = 777L; + private long COMPANY_ID; private Company TEST_COMPANY; private DocumentTypes TEST_DOCUMENT_TYPE = DocumentTypes.cio; @@ -86,9 +86,8 @@ class ProfileDocumentServiceTest { this.companyMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); TEST_COMPANY = new Company(); - TEST_COMPANY.setId(COMPANY_ID); TEST_COMPANY.setWorkflowStatus(WorkflowStatus.Active.getKey()); - companyMap.insert(TEST_COMPANY); + COMPANY_ID = companyMap.insert(TEST_COMPANY); Imdg documentTypeDictionaryImdg = hazelcastServiceTest.getImdg( IMDGDistributedNames.Map_DocumentTypeDictionary, From dec7f44e48160e8a3001c283edd51ead1dce4b45 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Wed, 5 Apr 2023 16:26:32 +0300 Subject: [PATCH 44/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83=20=D0=B7=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B5=D0=B9=20=D0=B2=20=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BE=D1=87=D0=BD=D0=B8=D0=BA=D0=B0=D1=85,=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B8,=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/securities-service/pom.xml | 17 ++ .../securities/component/ListingBuilder.java | 19 +- .../service/cud/EquitySecurityService.java | 4 +- .../cud/FixedIncomeSecurityService.java | 14 +- .../cud/MoneyMarketSecurityService.java | 7 +- .../service/cud/СurrencyService.java | 172 +++++++++++++++ .../validation/ValidationProvider.java | 94 +++++++- .../rule/HaveValidCodeByDictionary.java | 39 ++++ .../validation/rule/HaveValidCompanyId.java | 35 +++ .../IsValidInstrumentTypeFromRequest.java | 6 +- .../service/AbstractServiceTest.java | 53 +++++ .../service/EquitySecurityServiceTest.java | 9 +- .../FixedIncomeSecurityServiceTest.java | 207 +++++++++--------- .../service/MoneyMarketSecurityFactory.java | 25 ++- .../MoneyMarketSecurityServiceTest.java | 7 +- .../platform/messaging/domain/Consts.java | 4 + 16 files changed, 569 insertions(+), 143 deletions(-) create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java diff --git a/clearing-parent/securities-service/pom.xml b/clearing-parent/securities-service/pom.xml index 742105bf4..63e85f10a 100644 --- a/clearing-parent/securities-service/pom.xml +++ b/clearing-parent/securities-service/pom.xml @@ -77,6 +77,23 @@ ${project.artifactId} + + org.apache.maven.plugins + maven-surefire-plugin + 2.21.0 + + + org.junit.platform + junit-platform-surefire-provider + 1.2.0-M1 + + + org.junit.jupiter + junit-jupiter-engine + 5.2.0-M1 + + + diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java index d8cec1b88..376c068d2 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java @@ -13,12 +13,13 @@ import ru.spcex.platform.enumeration.Status; import java.math.BigDecimal; public class ListingBuilder { + private final String market = Market.mkrs.getKey(); public Listing byNewMms(MoneyMarketSecurity mms, MoneyMarketSecurityNewRequest mmsReq) { Listing listing = new Listing(); listing.setCreated(mms.getCreated()); listing.setSecurityId(mms.getId()); listing.setLotSize(BigDecimal.valueOf(mmsReq.getLotSize())); - listing.setMarket(Market.mkrs.getKey()); + listing.setMarket(market); listing.setSymbolCode(mms.getSecuritySymbol()); listing.setSymbolName(mms.getFullName()); listing.setTradingCurrency(mms.getNominalCurrency()); @@ -41,7 +42,7 @@ public class ListingBuilder { listing.setCreated(equitySecurity.getCreated()); listing.setSecurityId(equitySecurity.getId()); listing.setLotSize(BigDecimal.valueOf(request.getLotSize())); - listing.setMarket(Market.mkrs.getKey()); + listing.setMarket(market); listing.setSymbolCode(equitySecurity.getSecuritySymbol()); listing.setSymbolName(equitySecurity.getFullName()); // listing.setTradingCurrency(equitySecurity.getNominalCurrency()); @@ -54,6 +55,7 @@ public class ListingBuilder { listing.setSymbolCode(equitySecurity.getSecuritySymbol()); listing.setSymbolName(equitySecurity.getFullName()); listing.setWorkflowStatus(equitySecurity.getWorkflowStatus()); + listing.setMarket(market); listing.setLotSize(equitySecurity.getLotSize()); listing.setUpdated(equitySecurity.getUpdated()); return listing; @@ -64,11 +66,22 @@ public class ListingBuilder { listing.setCreated(instant.getCreated()); listing.setSecurityId(instant.getId()); listing.setLotSize(BigDecimal.valueOf(request.getLotSize())); - listing.setMarket(Market.mkrs.getKey()); + listing.setMarket(market); listing.setSymbolCode(instant.getSecuritySymbol()); listing.setSymbolName(instant.getFullName()); listing.setTradingCurrency(instant.getNominalCurrency()); listing.setWorkflowStatus(Status.Active.getKey()); return listing; } + + public Listing byFixedIncomeEquity(FixedIncomeSecurity fixedIncomeSecurity, Listing listing) { + listing.setSecurityId(fixedIncomeSecurity.getId()); + listing.setSymbolCode(fixedIncomeSecurity.getSecuritySymbol()); + listing.setSymbolName(fixedIncomeSecurity.getFullName()); + listing.setTradingCurrency(fixedIncomeSecurity.getNominalCurrency()); + listing.setWorkflowStatus(fixedIncomeSecurity.getWorkflowStatus()); + listing.setLotSize(fixedIncomeSecurity.getLotSize()); + listing.setUpdated(fixedIncomeSecurity.getUpdated()); + return listing; + } } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java index 4744748b9..e7accd308 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java @@ -89,7 +89,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing equity.setIssuerId(req.getIssuerId()); equity.setShortNameEng(req.getShortNameEng()); equity.setFullNameEng(req.getFullNameEng()); - equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + equity.setWorkflowStatus(req.workflowStatus); equity.setInstrumentType(req.getInstrumentType()); equity.setSecurityId(equity.getId()); equity.setCreated(Instant.now()); @@ -132,7 +132,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing equity.setIssuerId(req.getIssuerId()); equity.setShortNameEng(req.getShortNameEng()); equity.setFullNameEng(req.getFullNameEng()); - equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + equity.setWorkflowStatus(req.workflowStatus); equity.setInstrumentType(req.getInstrumentType()); equitySecurityImdg.update(equity); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java index bb5b8af08..aa6c36cee 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java @@ -94,7 +94,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial fixedIncome.setIssuerId(req.getIssuerId()); fixedIncome.setShortNameEng(req.getShortNameEng()); fixedIncome.setFullNameEng(req.getFullNameEng()); - fixedIncome.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + fixedIncome.setWorkflowStatus(req.getWorkflowStatus()); fixedIncome.setInstrumentType(req.getInstrumentType()); fixedIncome.setSecurityId(fixedIncome.getId()); fixedIncome.setCreated(Instant.now()); @@ -142,7 +142,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial fixedIncome.setIssuerId(req.getIssuerId()); fixedIncome.setShortNameEng(req.getShortNameEng()); fixedIncome.setFullNameEng(req.getFullNameEng()); - fixedIncome.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + fixedIncome.setWorkflowStatus(req.getWorkflowStatus()); fixedIncome.setInstrumentType(req.getInstrumentType()); fixedIncome.setSecurityId(fixedIncome.getId()); @@ -152,13 +152,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId()); return null; } - listing.setSecurityId(fixedIncome.getId()); - listing.setSymbolCode(fixedIncome.getSecuritySymbol()); - listing.setSymbolName(fixedIncome.getFullName()); - listing.setTradingCurrency(fixedIncome.getNominalCurrency()); - listing.setWorkflowStatus(fixedIncome.getWorkflowStatus()); - listing.setLotSize(fixedIncome.getLotSize()); - listing.setUpdated(updateTime); + listing = listingBuilder.byFixedIncomeEquity(fixedIncome, listing); listingImdg.update(listing); return null; } @@ -167,7 +161,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial CommonDeleteRequest req = userRequest.getRequestPayload(); log.debug("CommonDeleteRequest received id = {}", req.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityDeleteValidator()); + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeDeleteValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; Instant updateTime = Instant.now(); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java index 493124d92..383610af8 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java @@ -118,10 +118,11 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setSecuritySymbol(req.getSecuritySymbol()); mms.setTermType(req.getTermType()); mms.setIsin(req.getIsin()); + mms.setIssuerId(req.getIssuerId()); mms.setSecurityId(mms.getId()); mms.setDescription(req.getDescription()); mms.setCreated(Instant.now()); - mms.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + mms.setWorkflowStatus(req.getWorkflowStatus()); try { transaction.beginTransaction(); Imdg moneyMarketSecurityMap = transaction.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class); @@ -171,8 +172,10 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setSecuritySymbol(req.getSecuritySymbol()); mms.setTermType(req.getTermType()); mms.setIsin(req.getIsin()); + mms.setIssuerId(req.getIssuerId()); mms.setSecurityId(mms.getId()); - mms.setDescription(mms.getDescription()); + mms.setDescription(req.getDescription()); + mms.setWorkflowStatus(req.getWorkflowStatus()); moneyMarketSecurityMap.update(mms); Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java new file mode 100644 index 000000000..779b46eca --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java @@ -0,0 +1,172 @@ +package ru.spcex.clearing.securities.service.cud; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; +import ru.clearing.classes.statics.data.misc.Listing; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.securities.component.ListingBuilder; +import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.ImdgTransaction; + +import java.math.BigDecimal; +import java.time.Instant; +import java.util.Map; + +@Service +public class СurrencyService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg equitySecurityImdg; + private final Imdg listingImdg; + private final ImdgProvider imdgProvider; + private final ImdgId idGenerator; + private final ValidationProvider validation; + private final ValidationHelper validationHelper; + private final ListingBuilder listingBuilder = new ListingBuilder(); + + @Autowired + public СurrencyService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationProvider validation, + ValidationHelper validationHelper) { + super(kafkaQueue, kafkaProducer); + this.validation = validation; + this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); + this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.validationHelper = validationHelper; + } + + @Override + public void afterPropertiesSet() { + callback(EquitySecurityNewRequest.class) + .setFunction(this::newEquity) + .forDestination(Consts.DESTINATION_СURRENCY_NEW, callbacks::put); + callback(EquitySecurityUpdateRequest.class) + .setFunction(this::updateEquity) + .forDestination(Consts.DESTINATION_СURRENCY_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::deleteEquity) + .forDestination(Consts.DESTINATION_СURRENCY_DELETE, callbacks::put); + imdgProvider.waitAvailable(); + init(); + } + + private RequestInfoUpdate newEquity(BaseRequest userRequest) { + ImdgTransaction transaction = imdgProvider.newTransaction(); + EquitySecurityNewRequest req = userRequest.getRequestPayload(); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityNewValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + log.debug("EquitySecurityNewRequest received"); + EquitySecurity equity = new EquitySecurity(); + equity.setId(idGenerator.nextId()); + equity.setSecuritySymbol(req.getSecuritySymbol()); + equity.setShortName(req.getShortName()); + equity.setFullName(req.getFullName()); + equity.setIsin(req.getIsin()); + equity.setShareType(req.getShareType()); + equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setIssuerId(req.getIssuerId()); + equity.setShortNameEng(req.getShortNameEng()); + equity.setFullNameEng(req.getFullNameEng()); + equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + equity.setInstrumentType(req.getInstrumentType()); + equity.setSecurityId(equity.getId()); + equity.setCreated(Instant.now()); + try { + transaction.beginTransaction(); + Imdg equityImdg = transaction.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); + Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + //одним скопом выполняем реквест + equityImdg.insert(equity); + Listing listing = listingBuilder.byNewEquity(equity, req); + listingMap.insert(listing); + //и сохраняем обновленный +// reqInfoMap.insert(reqInfo); + transaction.commitTransaction(); + } catch (Throwable e) { + transaction.rollbackTransaction(); +// RequestInfo.update(reqInfo, Status.Error, ExceptionUtils.getStackTrace(e)); +// requestInfoImdg.insert(reqInfo); + } + log.debug("successfully processed, request id {}, new object id {}", userRequest.getId(), equity.getId()); + return null; // default success + } + + private RequestInfoUpdate updateEquity(BaseRequest userRequest) { + EquitySecurityUpdateRequest req = userRequest.getRequestPayload(); + log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityUpdateValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + EquitySecurity equity = equitySecurityImdg.getSingleObjectByID(req.getId()); + Instant updateTime = Instant.now(); + equity.setUpdated(updateTime); + equity.setSecuritySymbol(req.getSecuritySymbol()); + equity.setShortName(req.getShortName()); + equity.setFullName(req.getFullName()); + equity.setIsin(req.getIsin()); + equity.setShareType(req.getShareType()); + equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setIssuerId(req.getIssuerId()); + equity.setShortNameEng(req.getShortNameEng()); + equity.setFullNameEng(req.getFullNameEng()); + equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + equity.setInstrumentType(req.getInstrumentType()); + + equitySecurityImdg.update(equity); + Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); + if (listing == null) { + log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); + return null; + } + listing = listingBuilder.byUpdateEquity(equity, listing); + listingImdg.update(listing); + return null; + } + + private RequestInfoUpdate deleteEquity(BaseRequest userRequest) { + CommonDeleteRequest req = userRequest.getRequestPayload(); + log.debug("CommonDeleteRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityDeleteValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + Instant updateTime = Instant.now(); + EquitySecurity equity = equitySecurityImdg.getSingleObjectByID(req.getId()); + equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + equity.setUpdated(updateTime); + equitySecurityImdg.update(equity); + + Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); + if (listing == null) { + log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); + return null; + } + listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + listing.setUpdated(updateTime); + listingImdg.update(listing); + return null; + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index 40371d3a4..ae176fd6a 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -21,12 +21,26 @@ public class ValidationProvider { private final Imdg mmsMap; private final Imdg equityMap; private final Imdg fixedIncomeMap; + private final Imdg instrumentTypeDictionaryImdg; + private final Imdg workflowStatusDictionaryImdg; + private final Imdg termTypeDictionaryImdg; + private final Imdg currencyCodeDictionaryImdg; + private final Imdg shareTypeDictionaryImdg; + private final Imdg bondTypeDictionaryImdg; + private final Imdg companyImdg; public ValidationProvider(ImdgProvider imdgProvider) { this.mmsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, SpcexObjectBase.class); this.equityMap = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, SpcexObjectBase.class); this.fixedIncomeMap = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, SpcexObjectBase.class); + this.instrumentTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, SpcexObjectBase.class); + this.workflowStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, SpcexObjectBase.class); + this.termTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TermTypeDictionary, SpcexObjectBase.class); + this.currencyCodeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, SpcexObjectBase.class); + this.shareTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ShareTypeDictionary, SpcexObjectBase.class); + this.bondTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BondTypeDictionary, SpcexObjectBase.class); + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, SpcexObjectBase.class); } public Function mmsNewValidator() { @@ -34,11 +48,21 @@ public class ValidationProvider { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(mmsRequest); context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); + context.addImdg(IMDGDistributedNames.Map_Company, companyImdg); + context.addImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, instrumentTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_TermTypeDictionary, termTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg); return new ValidatorImpl<>(context, EndDtAfterStartDt.instance(MoneyMarketSecurityNewRequest.class), new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentAlreadyExists, MoneyMarketSecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "RATE"), - MmsNewValidationRule.RequiredFieldIsNotEmpty + MmsNewValidationRule.RequiredFieldIsNotEmpty, + new HaveValidCompanyId<>(MoneyMarketSecurityNewRequest::getIssuerId, "issuerId"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, MoneyMarketSecurityNewRequest::getInstrumentType, "instrumentType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityNewRequest::getWorkflowStatus, "workflowStatus"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_TermTypeDictionary, MoneyMarketSecurityNewRequest::getTermType, "termType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, MoneyMarketSecurityNewRequest::getNominalCurrency, "nominalCurrency") ); }; } @@ -48,11 +72,21 @@ public class ValidationProvider { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(mmsRequest); context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); + context.addImdg(IMDGDistributedNames.Map_Company, companyImdg); + context.addImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, instrumentTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_TermTypeDictionary, termTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg); return new ValidatorImpl<>(context, EndDtAfterStartDt.instance(MoneyMarketSecurityUpdateRequest.class), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), - new WorkflowStatusActv() + new WorkflowStatusActv(), + new HaveValidCompanyId<>(MoneyMarketSecurityUpdateRequest::getIssuerId, "issuerId"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, MoneyMarketSecurityUpdateRequest::getInstrumentType, "instrumentType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityUpdateRequest::getWorkflowStatus, "workflowStatus"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_TermTypeDictionary, MoneyMarketSecurityUpdateRequest::getTermType, "termType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, MoneyMarketSecurityUpdateRequest::getNominalCurrency, "nominalCurrency") ); }; } @@ -74,12 +108,19 @@ public class ValidationProvider { return equityRequest -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_Company, companyImdg); context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); + context.addImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, instrumentTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_ShareTypeDictionary, shareTypeDictionaryImdg); return new ValidatorImpl<>(context, new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentAlreadyExists, EquitySecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "EQTY"), - EquityNewValidationRule.RequiredFieldIsNotEmpty - ); + EquityNewValidationRule.RequiredFieldIsNotEmpty, + new HaveValidCompanyId<>(EquitySecurityNewRequest::getIssuerId, "issuerId"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, EquitySecurityNewRequest::getInstrumentType, "instrumentType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityNewRequest::getWorkflowStatus, "workflowStatus"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_ShareTypeDictionary, EquitySecurityNewRequest::getShareType, "shareType")); }; } @@ -88,11 +129,18 @@ public class ValidationProvider { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(equityRequest); context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); + context.addImdg(IMDGDistributedNames.Map_Company, companyImdg); + context.addImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, instrumentTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_ShareTypeDictionary, shareTypeDictionaryImdg); return new ValidatorImpl<>(context, new PresentById(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "EQTY"), - new WorkflowStatusActv() - ); + new WorkflowStatusActv(), + new HaveValidCompanyId<>(EquitySecurityUpdateRequest::getIssuerId, "issuerId"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, EquitySecurityUpdateRequest::getInstrumentType, "instrumentType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityUpdateRequest::getWorkflowStatus, "workflowStatus"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_ShareTypeDictionary, EquitySecurityUpdateRequest::getShareType, "shareType")); }; } @@ -113,12 +161,22 @@ public class ValidationProvider { return equityRequest -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(equityRequest); - context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, equityMap); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, fixedIncomeMap); + context.addImdg(IMDGDistributedNames.Map_Company, companyImdg); + context.addImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, instrumentTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_BondTypeDictionary, bondTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg); return new ValidatorImpl<>(context, new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentAlreadyExists, FixedIncomeSecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "BOND"), - FixedIncomeNewValidationRule.RequiredFieldIsNotEmpty - ); + FixedIncomeNewValidationRule.RequiredFieldIsNotEmpty, + new HaveValidCompanyId<>(FixedIncomeSecurityNewRequest::getIssuerId, "issuerId"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, FixedIncomeSecurityNewRequest::getInstrumentType, "instrumentType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityNewRequest::getWorkflowStatus, "workflowStatus"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_BondTypeDictionary, FixedIncomeSecurityNewRequest::getBondType, "bondType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, FixedIncomeSecurityNewRequest::getNominalCurrency, "nominalCurrency") + ); }; } @@ -126,11 +184,22 @@ public class ValidationProvider { return equityRequest -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(equityRequest); - context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, equityMap); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, fixedIncomeMap); + context.addImdg(IMDGDistributedNames.Map_Company, companyImdg); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, fixedIncomeMap); + context.addImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, instrumentTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_BondTypeDictionary, bondTypeDictionaryImdg); + context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg); return new ValidatorImpl<>(context, new PresentById(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "BOND"), - new WorkflowStatusActv() + new WorkflowStatusActv(), + new HaveValidCompanyId<>(FixedIncomeSecurityUpdateRequest::getIssuerId, "issuerId"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, FixedIncomeSecurityUpdateRequest::getInstrumentType, "instrumentType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityUpdateRequest::getWorkflowStatus, "workflowStatus"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_BondTypeDictionary, FixedIncomeSecurityUpdateRequest::getBondType, "bondType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, FixedIncomeSecurityUpdateRequest::getNominalCurrency, "nominalCurrency") ); }; } @@ -139,7 +208,8 @@ public class ValidationProvider { return equityRequest -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(equityRequest); - context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, equityMap); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, fixedIncomeMap); + context.addImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, fixedIncomeMap); return new ValidatorImpl<>(context, new PresentById(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "BOND"), diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java new file mode 100644 index 000000000..5ec7f2ec6 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java @@ -0,0 +1,39 @@ +package ru.spcex.clearing.securities.validation.rule; + +import org.springframework.util.StringUtils; +import ru.spcex.clearing.securities.errors.SecuritiesError; +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.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; + +public class HaveValidCodeByDictionary implements IValidationRule> { + String mapName; + String errArg; + Function codeGetter; + public HaveValidCodeByDictionary(String mapName, Function codeGetter, String errArg) { + this.mapName = mapName; + this.codeGetter = codeGetter; + this.errArg = errArg; + } + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + String code = codeGetter.apply(validatedObject); + if(!StringUtils.hasText(code)) { + return of(SecuritiesError.RequiredFieldIsEmpty, errArg); + } + Imdg imdgDictionary = context.obtainMap(mapName, SpcexObjectBase.class); + SpcexObjectBase dictionary = imdgDictionary.getSingleObjectByFieldValues(Map.of( + "code", code)); + if (dictionary == null) { + return of(SecuritiesError.WrongFieldValue, errArg); + } + return empty(); + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java new file mode 100644 index 000000000..914fa2903 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java @@ -0,0 +1,35 @@ +package ru.spcex.clearing.securities.validation.rule; + +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.securities.errors.SecuritiesError; +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.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; +import java.util.function.Function; + +public class HaveValidCompanyId implements IValidationRule> { + Function idGetter; + String errArg; + public HaveValidCompanyId(Function idGetter, String errArg) { + this.idGetter = idGetter; + this.errArg = errArg; + } + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + Long id = idGetter.apply(validatedObject); + if(id == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, errArg); + } + Imdg imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_Company, SpcexObjectBase.class); + SpcexObjectBase dictionary = imdgDictionary.getSingleObjectByID(id); + if (dictionary == null) { + return of(SecuritiesError.WrongFieldValue, errArg); + } + return empty(); + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java index a051e0916..76aa065ba 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java @@ -17,15 +17,15 @@ public class IsValidInstrumentTypeFromRequest implements IValidationRule validate(ImdgValidationContext context) { WithInstrumentType action = context.getValidatedObject(); if (action.getInstrumentType() == null) { return of(SecuritiesError.RequiredFieldIsEmpty); - } else if (!predictableInstrumentType.equalsIgnoreCase(action.getInstrumentType())){ + } else if (!predictableInstrumentType.equalsIgnoreCase(action.getInstrumentType())) { return of(errorEnum); - }else { + } else { return empty(); } } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java index 391580ce8..86bc623f9 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -10,10 +10,12 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.mock.mockito.MockBean; 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.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.config.ErrorResolverConfig; @@ -52,6 +54,22 @@ public abstract class AbstractServiceTest { protected Imdg listingImdg; protected Imdg equitySecurityImdg; protected Imdg fixedIncomeSecurityImdg; + protected Imdg instrumentTypeDictionaryImdg; + protected Imdg workflowStatusDictionaryImdg; + protected Imdg termTypeDictionaryImdg; + protected Imdg currencyCodeDictionaryImdg; + protected Imdg shareTypeDictionaryImdg; + protected Imdg bondTypeDictionaryImdg; + protected Imdg companyImdg; + + public static String RATE = "RATE"; + protected String EQTY = "EQTY"; + protected String BOND = "BOND"; + protected String shareType = "shareType"; + protected String bondType = "bondType"; + public static Long issuerId = 13243L; + public static String termType = "TermType"; + public static String currencyCode = "RUB"; protected final ListingBuilder listingBuilder = new ListingBuilder(); @Captor protected ArgumentCaptor producerRecord; @@ -67,7 +85,42 @@ public abstract class AbstractServiceTest { this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); this.fixedIncomeSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class); + this.instrumentTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_InstrumentTypeDictionary, InstrumentTypeDictionary.class); + this.workflowStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); + this.termTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TermTypeDictionary, TermTypeDictionary.class); + this.currencyCodeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class); + this.shareTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ShareTypeDictionary, ShareTypeDictionary.class); + this.bondTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BondTypeDictionary, BondTypeDictionary.class); + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + InstrumentTypeDictionary instrumentTypeDictionary = new InstrumentTypeDictionary(); + instrumentTypeDictionary.setId(1L); + instrumentTypeDictionary.setCode(RATE); + instrumentTypeDictionaryImdg.insert(instrumentTypeDictionary); + instrumentTypeDictionary.setId(2L); + instrumentTypeDictionary.setCode(EQTY); + instrumentTypeDictionaryImdg.insert(instrumentTypeDictionary); + instrumentTypeDictionary.setId(3L); + instrumentTypeDictionary.setCode(BOND); + instrumentTypeDictionaryImdg.insert(instrumentTypeDictionary); + WorkflowStatusDictionary workflowStatusDictionary = new WorkflowStatusDictionary(); + workflowStatusDictionary.setCode(ru.spcex.platform.enumeration.Status.Active.getKey()); + workflowStatusDictionaryImdg.insert(workflowStatusDictionary); + TermTypeDictionary termTypeDictionary = new TermTypeDictionary(); + termTypeDictionary.setCode(termType); + termTypeDictionaryImdg.insert(termTypeDictionary); + CurrencyCodeDictionary currencyCodeDictionary = new CurrencyCodeDictionary(); + currencyCodeDictionary.setCode(currencyCode); + currencyCodeDictionaryImdg.insert(currencyCodeDictionary); + ShareTypeDictionary shareTypeDictionary = new ShareTypeDictionary(); + shareTypeDictionary.setCode(shareType); + shareTypeDictionaryImdg.insert(shareTypeDictionary); + BondTypeDictionary bondTypeDictionary = new BondTypeDictionary(); + bondTypeDictionary.setCode(bondType); + bondTypeDictionaryImdg.insert(bondTypeDictionary); + Company company = new Company(); + company.setId(issuerId); + companyImdg.insert(company); TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); doReturn(future).when(mockProducer).send(producerRecord.capture()); } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java index 960212afc..d34e89aff 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java @@ -49,6 +49,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ */ @Test public void testNewEquity(){ + clearAllInImdg(equitySecurityImdg); final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_NEW; final EquitySecurity equityPrediction = getEquitySecurity(); @@ -86,6 +87,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ */ @Test public void testUpdateEquity() { + clearAllInImdg(equitySecurityImdg); final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_UPDATE; String fullName = "FullNameUpdate"; Double updateLotSize = 12.0; @@ -126,6 +128,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ */ @Test public void testDeleteEquity(){ + clearAllInImdg(equitySecurityImdg); final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_DELETE; final EquitySecurity equityPrediction = getEquitySecurity(); @@ -165,13 +168,13 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ equitySecurity.setShortName("ShortNameNewEquity"); equitySecurity.setFullName("FullNameNewEquity"); equitySecurity.setIsin("Isin"); - equitySecurity.setShareType("ShareType"); + equitySecurity.setShareType(shareType); equitySecurity.setLotSize(BigDecimal.valueOf(18.0d)); - equitySecurity.setIssuerId(11L); + equitySecurity.setIssuerId(issuerId); equitySecurity.setShortNameEng("ShortNameNewEquity"); equitySecurity.setFullNameEng("FullNameNewEquity"); equitySecurity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); - equitySecurity.setInstrumentType("EQTY"); + equitySecurity.setInstrumentType(EQTY); return equitySecurity; } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java index 9e19f531e..92ae716b9 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java @@ -3,15 +3,14 @@ package ru.spcex.clearing.securities.service; import org.apache.kafka.clients.consumer.MockConsumer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; @@ -51,6 +50,7 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ */ @Test public void newFixedIncome(){ + clearAllInImdg(fixedIncomeSecurityImdg); final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_NEW; final FixedIncomeSecurity fixedIncomePrediction = getFixedIncomeSecurity(); @@ -88,38 +88,38 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ */ @Test public void updateFixedIncome() { -// clearAllInImdg(moneyMarketSecurityMap); -// final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_UPDATE; -// String fullName = "FullNameUpdate"; -// Double updateLotSize = 12.0; -// -// final FixedIncomeSecurity fixedIncomePrediction = getFixedIncomeSecurity(); -// -// fixedIncomeSecurityImdg.insert(fixedIncomePrediction); -// fixedIncomePrediction.setFullName(fullName); -// fixedIncomePrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); -// final FixedIncomeSecurityUpdateRequest request = getEquitySecurityUpdateRequest(fixedIncomePrediction); -// Listing listingPrediction = new Listing(); -// listingPrediction = listingBuilder.byUpdateEquity(fixedIncomePrediction, listingPrediction); -// listingImdg.insert(listingPrediction); -// -// //ACT -// String jsonString = getJsonStringForUPDATE(request, ID); -// -// addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); -// -// //ASSERT -// waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); -// -// EquitySecurity equityResult = equitySecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", fixedIncomePrediction.getFullName())); -// fixedIncomePrediction.setId(equityResult.getId()); -// fixedIncomePrediction.setSecurityId(equityResult.getSecurityId()); -// FIXED_INCOME_SECURITY_MATCHER.assertMatch(equityResult, fixedIncomePrediction); -// -// Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncomePrediction.getId())); -// listingPrediction.setId(listingResult.getId()); -// listingPrediction.setSecurityId(listingResult.getSecurityId()); -// LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + clearAllInImdg(moneyMarketSecurityMap); + final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_UPDATE; + String fullName = "FullNameUpdate"; + Double updateLotSize = 12.0; + + final FixedIncomeSecurity fixedIncomePrediction = getFixedIncomeSecurity(); + + fixedIncomeSecurityImdg.insert(fixedIncomePrediction); + fixedIncomePrediction.setFullName(fullName); + fixedIncomePrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); + final FixedIncomeSecurityUpdateRequest request = getFixedIncomeSecurityUpdateRequest(fixedIncomePrediction); + Listing listingPrediction = new Listing(); + listingPrediction = listingBuilder.byFixedIncomeEquity(fixedIncomePrediction, listingPrediction); + listingImdg.insert(listingPrediction); + + //ACT + String jsonString = getJsonStringForUPDATE(request, ID); + + addRecordToKafka((MockConsumer) fixedIncomeSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + FixedIncomeSecurity equityResult = fixedIncomeSecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", fixedIncomePrediction.getFullName())); + fixedIncomePrediction.setId(equityResult.getId()); + fixedIncomePrediction.setSecurityId(equityResult.getSecurityId()); + FIXED_INCOME_SECURITY_MATCHER.assertMatch(equityResult, fixedIncomePrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncomePrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); } /** @@ -130,37 +130,37 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ */ @Test public void deleteFixedIncome(){ -// clearAllInImdg(moneyMarketSecurityMap); -// final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_DELETE; -// -// final EquitySecurity equityPrediction = getFixedIncomeSecurity(); -// equitySecurityImdg.insert(equityPrediction); -// equityPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); -// -// Listing listingPrediction = new Listing(); -// listingPrediction = listingBuilder.byUpdateEquity(equityPrediction, listingPrediction); -// listingImdg.insert(listingPrediction);listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); -// -// CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); -// commonDeleteRequest.setId(ID); -// -// //ACT -// String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID); -// -// addRecordToKafka((MockConsumer) equitySecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); -// -// //ASSERT -// waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); -// -// EquitySecurity equityResult = equitySecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", equityPrediction.getFullName())); -// equityPrediction.setId(equityResult.getId()); -// equityPrediction.setSecurityId(equityResult.getSecurityId()); -// FIXED_INCOME_SECURITY_MATCHER.assertMatch(equityResult, equityPrediction); -// -// Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equityPrediction.getId())); -// listingPrediction.setId(listingResult.getId()); -// listingPrediction.setSecurityId(listingResult.getSecurityId()); -// LISTING_MATCHER.assertMatch(listingResult, listingPrediction); + clearAllInImdg(moneyMarketSecurityMap); + final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_DELETE; + + final FixedIncomeSecurity fixedIncomePrediction = getFixedIncomeSecurity(); + fixedIncomeSecurityImdg.insert(fixedIncomePrediction); + fixedIncomePrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + + Listing listingPrediction = new Listing(); + listingPrediction = listingBuilder.byFixedIncomeEquity(fixedIncomePrediction, listingPrediction); + listingImdg.insert(listingPrediction);listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + + CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); + commonDeleteRequest.setId(ID); + + //ACT + String jsonString = getJsonStringForDELETE(commonDeleteRequest, ID); + + addRecordToKafka((MockConsumer) fixedIncomeSecurityService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + FixedIncomeSecurity equityResult = fixedIncomeSecurityImdg.getSingleObjectBySQL(String.format("fullName = %s", fixedIncomePrediction.getFullName())); + fixedIncomePrediction.setId(equityResult.getId()); + fixedIncomePrediction.setSecurityId(equityResult.getSecurityId()); + FIXED_INCOME_SECURITY_MATCHER.assertMatch(equityResult, fixedIncomePrediction); + + Listing listingResult = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncomePrediction.getId())); + listingPrediction.setId(listingResult.getId()); + listingPrediction.setSecurityId(listingResult.getSecurityId()); + LISTING_MATCHER.assertMatch(listingResult, listingPrediction); } private FixedIncomeSecurity getFixedIncomeSecurity(){ @@ -170,58 +170,63 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ fixedIncome.setShortName("ShortNameNewEquity"); fixedIncome.setFullName("FullNameNewEquity"); fixedIncome.setIsin("Isin"); - fixedIncome.setBondType("BondType"); + fixedIncome.setBondType(bondType); fixedIncome.setLotSize(BigDecimal.valueOf(18.0d)); fixedIncome.setNominalValue(BigDecimal.valueOf(18.0d)); - fixedIncome.setNominalCurrency("NominalCurrency"); + fixedIncome.setNominalCurrency(currencyCode); fixedIncome.setMaturityDate(LocalDate.now()); fixedIncome.setCoupon(BigDecimal.valueOf(18.0d)); fixedIncome.setCouponFrequency(9L); - fixedIncome.setIssuerId(11L); + fixedIncome.setIssuerId(issuerId); fixedIncome.setShortNameEng("ShortNameNewEquity"); fixedIncome.setFullNameEng("FullNameNewEquity"); fixedIncome.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); - fixedIncome.setInstrumentType("BOND"); + fixedIncome.setInstrumentType(BOND); fixedIncome.setSecurityId(fixedIncome.getId()); return fixedIncome; } private FixedIncomeSecurityNewRequest getFixedIncomeSecurityNewRequest(FixedIncomeSecurity fixedIncomeSecurity){ - FixedIncomeSecurityNewRequest equitySecurityNewRequest = new FixedIncomeSecurityNewRequest(); - equitySecurityNewRequest.setSecuritySymbol(fixedIncomeSecurity.getSecuritySymbol()); - equitySecurityNewRequest.setShortName(fixedIncomeSecurity.getShortName()); - equitySecurityNewRequest.setFullName(fixedIncomeSecurity.getFullName()); - equitySecurityNewRequest.setIsin(fixedIncomeSecurity.getIsin()); - equitySecurityNewRequest.setBondType(fixedIncomeSecurity.getBondType()); - equitySecurityNewRequest.setLotSize(fixedIncomeSecurity.getLotSize().doubleValue()); - equitySecurityNewRequest.setNominalValue(fixedIncomeSecurity.getNominalValue().doubleValue()); - equitySecurityNewRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); - equitySecurityNewRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); - equitySecurityNewRequest.setCoupon(fixedIncomeSecurity.getCoupon().doubleValue()); - equitySecurityNewRequest.setCouponFrequency(9L); - equitySecurityNewRequest.setIssuerId(fixedIncomeSecurity.getIssuerId()); - equitySecurityNewRequest.setShortNameEng(fixedIncomeSecurity.getShortNameEng()); - equitySecurityNewRequest.setFullNameEng(fixedIncomeSecurity.getFullNameEng()); - equitySecurityNewRequest.setWorkflowStatus(fixedIncomeSecurity.getWorkflowStatus()); - equitySecurityNewRequest.setInstrumentType(fixedIncomeSecurity.getInstrumentType()); - return equitySecurityNewRequest; + FixedIncomeSecurityNewRequest fixedIncomeSecurityNewRequest = new FixedIncomeSecurityNewRequest(); + fixedIncomeSecurityNewRequest.setSecuritySymbol(fixedIncomeSecurity.getSecuritySymbol()); + fixedIncomeSecurityNewRequest.setShortName(fixedIncomeSecurity.getShortName()); + fixedIncomeSecurityNewRequest.setFullName(fixedIncomeSecurity.getFullName()); + fixedIncomeSecurityNewRequest.setIsin(fixedIncomeSecurity.getIsin()); + fixedIncomeSecurityNewRequest.setBondType(fixedIncomeSecurity.getBondType()); + fixedIncomeSecurityNewRequest.setLotSize(fixedIncomeSecurity.getLotSize().doubleValue()); + fixedIncomeSecurityNewRequest.setNominalValue(fixedIncomeSecurity.getNominalValue().doubleValue()); + fixedIncomeSecurityNewRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); + fixedIncomeSecurityNewRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); + fixedIncomeSecurityNewRequest.setCoupon(fixedIncomeSecurity.getCoupon().doubleValue()); + fixedIncomeSecurityNewRequest.setCouponFrequency(fixedIncomeSecurity.getCouponFrequency()); + fixedIncomeSecurityNewRequest.setIssuerId(fixedIncomeSecurity.getIssuerId()); + fixedIncomeSecurityNewRequest.setShortNameEng(fixedIncomeSecurity.getShortNameEng()); + fixedIncomeSecurityNewRequest.setFullNameEng(fixedIncomeSecurity.getFullNameEng()); + fixedIncomeSecurityNewRequest.setWorkflowStatus(fixedIncomeSecurity.getWorkflowStatus()); + fixedIncomeSecurityNewRequest.setInstrumentType(fixedIncomeSecurity.getInstrumentType()); + return fixedIncomeSecurityNewRequest; } - private EquitySecurityUpdateRequest getEquitySecurityUpdateRequest(EquitySecurity equitySecurity){ - EquitySecurityUpdateRequest equitySecurityUpdateRequest = new EquitySecurityUpdateRequest(); - equitySecurityUpdateRequest.setId(equitySecurity.getId()); - equitySecurityUpdateRequest.setSecuritySymbol(equitySecurity.getSecuritySymbol()); - equitySecurityUpdateRequest.setShortName(equitySecurity.getShortName()); - equitySecurityUpdateRequest.setFullName(equitySecurity.getFullName()); - equitySecurityUpdateRequest.setIsin(equitySecurity.getIsin()); - equitySecurityUpdateRequest.setShareType(equitySecurity.getShareType()); - equitySecurityUpdateRequest.setLotSize(equitySecurity.getLotSize().doubleValue()); - equitySecurityUpdateRequest.setIssuerId(equitySecurity.getIssuerId()); - equitySecurityUpdateRequest.setShortNameEng(equitySecurity.getShortNameEng()); - equitySecurityUpdateRequest.setFullNameEng(equitySecurity.getFullNameEng()); - equitySecurityUpdateRequest.setWorkflowStatus(equitySecurity.getWorkflowStatus()); - equitySecurityUpdateRequest.setInstrumentType(equitySecurity.getInstrumentType()); + private FixedIncomeSecurityUpdateRequest getFixedIncomeSecurityUpdateRequest(FixedIncomeSecurity fixedIncomeSecurity){ + FixedIncomeSecurityUpdateRequest equitySecurityUpdateRequest = new FixedIncomeSecurityUpdateRequest(); + equitySecurityUpdateRequest.setId(fixedIncomeSecurity.getId()); + equitySecurityUpdateRequest.setSecuritySymbol(fixedIncomeSecurity.getSecuritySymbol()); + equitySecurityUpdateRequest.setShortName(fixedIncomeSecurity.getShortName()); + equitySecurityUpdateRequest.setFullName(fixedIncomeSecurity.getFullName()); + equitySecurityUpdateRequest.setIsin(fixedIncomeSecurity.getIsin()); + equitySecurityUpdateRequest.setBondType(fixedIncomeSecurity.getBondType()); + equitySecurityUpdateRequest.setLotSize(fixedIncomeSecurity.getLotSize().doubleValue()); + equitySecurityUpdateRequest.setNominalValue(fixedIncomeSecurity.getNominalValue().doubleValue()); + equitySecurityUpdateRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); + equitySecurityUpdateRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); + equitySecurityUpdateRequest.setCoupon(fixedIncomeSecurity.getCoupon().doubleValue()); + equitySecurityUpdateRequest.setCouponFrequency(fixedIncomeSecurity.getCouponFrequency()); + equitySecurityUpdateRequest.setIssuerId(fixedIncomeSecurity.getIssuerId()); + equitySecurityUpdateRequest.setShortNameEng(fixedIncomeSecurity.getShortNameEng()); + equitySecurityUpdateRequest.setFullNameEng(fixedIncomeSecurity.getFullNameEng()); + equitySecurityUpdateRequest.setWorkflowStatus(fixedIncomeSecurity.getWorkflowStatus()); + equitySecurityUpdateRequest.setInstrumentType(fixedIncomeSecurity.getInstrumentType()); return equitySecurityUpdateRequest; } } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java index fd66d5950..0ccfd0d7e 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java @@ -8,9 +8,11 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSe import java.math.BigDecimal; import java.time.LocalDate; +import static ru.spcex.clearing.securities.service.AbstractServiceTest.*; + class MoneyMarketSecurityFactory { - private String nominalCurrency = "RUB"; // (linked to currencyCode) + private String nominalCurrency = currencyCode; // (linked to currencyCode) private Long id = 0L; private Long securityId = 0L;// (linked to security) private String description = "tsetse"; @@ -18,11 +20,12 @@ class MoneyMarketSecurityFactory { private LocalDate startDate = LocalDate.ofEpochDay(0); private LocalDate endDate = LocalDate.now(); private BigDecimal nominalValue = BigDecimal.valueOf(1.0); - private String instrumentType = "RATE"; // (linked to instrumentType) + private String instrumentType = RATE; // (linked to instrumentType) private String fullName = "estat"; private String shortName = "esasdftat"; private String securitySymbol = "sdfafd"; - private String termType = "termType"; + private String istin = "istin"; + private String termType = AbstractServiceTest.termType; public String getFullName() { return fullName; @@ -88,7 +91,6 @@ class MoneyMarketSecurityFactory { moneyMarketSecurity.setId(id); moneyMarketSecurity.setSecurityId(securityId); - moneyMarketSecurity.setDescription(description); moneyMarketSecurity.setStartDate(startDate); moneyMarketSecurity.setEndDate(endDate); moneyMarketSecurity.setNominalValue(nominalValue); @@ -96,7 +98,11 @@ class MoneyMarketSecurityFactory { moneyMarketSecurity.setInstrumentType(instrumentType); moneyMarketSecurity.setFullName(fullName); moneyMarketSecurity.setShortName(shortName); + moneyMarketSecurity.setShortNameEng(shortName); + moneyMarketSecurity.setFullNameEng(fullName); + moneyMarketSecurity.setIsin(istin); moneyMarketSecurity.setTermType(termType); + moneyMarketSecurity.setIssuerId(issuerId); moneyMarketSecurity.setDescription(description); moneyMarketSecurity.setLotSize(BigDecimal.valueOf(lotSize)); moneyMarketSecurity.setSecuritySymbol(securitySymbol); @@ -118,9 +124,14 @@ class MoneyMarketSecurityFactory { moneyMarketSecurityUpdateRequest.setInstrumentType(instrumentType); moneyMarketSecurityUpdateRequest.setFullName(fullName); moneyMarketSecurityUpdateRequest.setShortName(shortName); + moneyMarketSecurityUpdateRequest.setShortNameEng(shortName); + moneyMarketSecurityUpdateRequest.setFullNameEng(fullName); + moneyMarketSecurityUpdateRequest.setIsin(istin); moneyMarketSecurityUpdateRequest.setTermType(termType); + moneyMarketSecurityUpdateRequest.setIssuerId(issuerId); moneyMarketSecurityUpdateRequest.setDescription(description); moneyMarketSecurityUpdateRequest.setSecuritySymbol(securitySymbol); + moneyMarketSecurityUpdateRequest.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); return moneyMarketSecurityUpdateRequest; } @@ -142,9 +153,15 @@ class MoneyMarketSecurityFactory { keyRequest.setInstrumentType(instrumentType); keyRequest.setFullName(fullName); keyRequest.setShortName(shortName); + keyRequest.setShortNameEng(shortName); + keyRequest.setFullNameEng(fullName); keyRequest.setTermType(termType); + keyRequest.setIssuerId(issuerId); + keyRequest.setIsin(istin); keyRequest.setDescription(description); keyRequest.setSecuritySymbol(securitySymbol); + keyRequest.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); + return keyRequest; } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java index 2f95ecb3e..5331b7e6f 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java @@ -141,16 +141,17 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{ clearAllInImdg(moneyMarketSecurityMap); final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE; String updateTermType = "updateTermType"; - Double updateLotSize = 12.0; + Double updateLotSize = 112.0; final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory .getMoneyMarketSecurity(); - moneyMarketSecurityMap.insert(moneyMarketSecurityPrediction); moneyMarketSecurityPrediction.setTermType(updateTermType); + moneyMarketSecurityMap.insert(moneyMarketSecurityPrediction); + moneyMarketSecurityPrediction.setTermType(termType); moneyMarketSecurityPrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); final MoneyMarketSecurityUpdateRequest keyRequest = moneyMarketSecurityFactory .getMoneyMarketSecurityUpdateRequest(); - keyRequest.setTermType(updateTermType); + keyRequest.setTermType(termType); keyRequest.setLotSize(updateLotSize); Listing listingPrediction = new Listing(); listingPrediction = listingBuilder.byUpdateMms(moneyMarketSecurityPrediction, listingPrediction); 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 5ee689fce..b4392e713 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 @@ -13,6 +13,10 @@ public interface Consts { String DESTINATION_FIXED_INCOME_SECURITY_UPDATE = "fixed-income-security-update"; String DESTINATION_FIXED_INCOME_SECURITY_DELETE = "fixed-income-security-delete"; + String DESTINATION_СURRENCY_NEW = "currency-new"; + String DESTINATION_СURRENCY_UPDATE = "currency-update"; + String DESTINATION_СURRENCY_DELETE = "currency-delete"; + String DESTINATION_KEY_RATE_NEW = "key-rate-new"; String DESTINATION_KEY_RATE_UPDATE = "key-rate-update"; String DESTINATION_KEY_RATE_DELETE = "key-rate-delete"; From c53374be1ee6ce4f11fcd4de4fb1997a3d7ef5f6 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 16:36:13 +0300 Subject: [PATCH 45/90] company-service: refactoring CompanyService --- .../company/service/CompanyInfoService.java | 36 +++++---- .../company/service/CompanyService.java | 80 ++++++++----------- .../company/service/CompanySymbolService.java | 17 ++++ .../domain/cud/company/CompanyNewRequest.java | 19 +++-- 4 files changed, 81 insertions(+), 71 deletions(-) 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 953bd35b8..84fd283e4 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,11 +22,13 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea private final Logger log = LoggerFactory.getLogger(getClass()); // private final Imdg companyInfoMap; private final Imdg companyMap; + protected final CompanyService companyService; @Autowired public CompanyInfoService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider) { + ImdgProvider imdgProvider, CompanyService companyService) { super(kafkaQueue, kafkaProducer); + this.companyService = companyService; // this.companyInfoMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyInfo, CompanyInfo.class); this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); } @@ -42,23 +44,25 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea public void companyInfoUpdate(BaseRequest userRequest) { CompanyInfoUpdateRequest req = userRequest.getRequestPayload(); log.debug("CompanyInfoUpdateRequest received"); + synchronized (companyService) { // CompanyInfo companyInfo = companyInfoMap.getSingleObjectByID(req.getId()); - Company company = companyMap.getSingleObjectByID(req.getId()); - CompanyInfo companyInfo = company == null ? null : company.getProfile(); + Company company = companyMap.getSingleObjectByID(req.getId()); + CompanyInfo companyInfo = company == null ? null : company.getProfile(); - companyInfo.setCorporationSoleType(req.getCorporationSoleType()); - companyInfo.setCountryCode(req.getCountryCode()); - companyInfo.setDescription(req.getDescription()); - companyInfo.setProfessionalSign(req.getProfessionalSign()); - companyInfo.setLegalKind(req.getLegalKind()); - companyInfo.setOrganizationType(req.getOrganizationType()); - companyInfo.setResidence(req.getResidence()); - companyInfo.setShortNameEng(req.getShortNameEng()); - companyInfo.setFullNameEng(req.getFullNameEng()); - companyInfo.setShortName(req.getShortName()); - companyInfo.setFullName(req.getFullName()); + companyInfo.setCorporationSoleType(req.getCorporationSoleType()); + companyInfo.setCountryCode(req.getCountryCode()); + companyInfo.setDescription(req.getDescription()); + companyInfo.setProfessionalSign(req.getProfessionalSign()); + companyInfo.setLegalKind(req.getLegalKind()); + companyInfo.setOrganizationType(req.getOrganizationType()); + companyInfo.setResidence(req.getResidence()); + companyInfo.setShortNameEng(req.getShortNameEng()); + companyInfo.setFullNameEng(req.getFullNameEng()); + companyInfo.setShortName(req.getShortName()); + companyInfo.setFullName(req.getFullName()); // companyInfoMap.update(companyInfo); - companyMap.update(company); - log.debug("successfully processed, id {}", companyInfo.getId()); + companyMap.update(company); + log.debug("successfully processed, id {}", companyInfo.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 c6f80e00e..c155a2b55 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 @@ -38,6 +38,8 @@ import java.util.function.Function; @Service public class CompanyService extends QueueConsumer implements InitializingBean { + protected static final Long SPVB_ID = 1L; // СПВБ + private final Logger log = LoggerFactory.getLogger(getClass()); private final RequestHelper requestHelper; private final Imdg companyMap; @@ -52,6 +54,8 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private Function companyUpdateRequestValidator; private Function companyDeleteRequestValidator; + protected CompanySymbolService companySymbolService; + @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, @@ -63,7 +67,9 @@ public class CompanyService extends QueueConsumer implements InitializingBean { @Qualifier("companyUpdateRequestValidator") Function companyUpdateRequestValidator, @Qualifier("CompanyDeleteRequestValidator") - Function companyDeleteRequestValidator + Function companyDeleteRequestValidator, + + CompanySymbolService companySymbolService ) { super(kafkaQueue, kafkaProducer); this.messageResolver = messageResolver; @@ -77,6 +83,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companyNewRequestValidator = companyNewRequestValidator; this.companyUpdateRequestValidator = companyUpdateRequestValidator; this.companyDeleteRequestValidator = companyDeleteRequestValidator; + this.companySymbolService = companySymbolService; } @Override @@ -122,32 +129,22 @@ public class CompanyService extends QueueConsumer implements InitializingBean { company.setFullName(req.getFullName()); if (req.getCompanySymbol() != null) { - CompanySymbols newSymbol = createCompanySymbol(company, req); + CompanySymbols newSymbol = companySymbolService.createCompanySymbol(company.getId(), req.getCompanySymbol(), req.getCompanySymbolValue()); updateCompanyBySymbol(company, newSymbol); - log.debug("Created new companySymbols.id={} for company {}", newSymbol.getId(), company.getId()); - companySymnbolsMap.insert(newSymbol); } - company.setWorkflowStatus(WorkflowStatus.Active.getKey()); + company.setWorkflowStatus(req.getWorkflowStatus()); companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); createNewRelation(company); - + if (!(WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))) { // Block + onChangeWorkflowStatus(company, null, company.getWorkflowStatus()); + } return null; } - protected CompanySymbols createCompanySymbol(Company forCompany, CompanyNewRequest request) { - //todo see CompanySymbolService - CompanySymbols newSymbol = new CompanySymbols(); - newSymbol.setId(idSequence.nextId()); - newSymbol.setCompanyId(forCompany.getId()); - newSymbol.setCompanySymbol(request.getCompanySymbol()); - newSymbol.setCompanySymbolValue(request.getCompanySymbolValue()); - return newSymbol; - } - private synchronized RequestInfoUpdate updateCompany(BaseRequest companyUpdateRequestBaseRequest) throws ValidationException { CompanyNewRequest updateRequest = companyUpdateRequestBaseRequest.getRequestPayload(); @@ -173,26 +170,20 @@ public class CompanyService extends QueueConsumer implements InitializingBean { if (updateRequest.getCompanySymbol() != null || updateRequest.getCompanySymbolValue() != null) { log.trace("Request field CompanySymbol, CompanySymbolValue ignore for update company request."); } - CompanySymbols companySymbol = companySymnbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); - if (companySymbol == null) { - log.warn("CompanySymbols not found for companyId={}", company.getId()); +// CompanySymbols не обновляем + + + String prevStatus = company.getWorkflowStatus(); + if (updateRequest.getWorkflowStatus() != null) { + company.setWorkflowStatus(updateRequest.getWorkflowStatus()); + if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { + onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); + } else { + log.trace("Status was not changed"); + } } else { - log.trace("Found CompanySymbols.id={} for companyId={}", companySymbol.getId(), company.getId()); - updateCompanyBySymbol(company, companySymbol); + log.trace("Null new WorkflowStatus"); } - - -// String prevStatus = company.getWorkflowStatus(); -// if (updateRequest.getWorkflowStatus() != null) { -// company.setWorkflowStatus(updateRequest.getWorkflowStatus()); -// if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { -// onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); -// } else { -// log.trace("Status was not changed"); -// } -// } else { -// log.trace("Null new WorkflowStatus"); -// } return null; } @@ -215,10 +206,12 @@ public class CompanyService extends QueueConsumer implements InitializingBean { } } + protected void kafkaSentAccountNotification(Company aboutBlockCompany) { + log.debug("Send message to kafka..."); + //todo message to queue + } - protected static final Long SPVB_ID = 1L; // СПВБ - - private void createNewRelation(Company company) { + protected void createNewRelation(Company company) { Relation relation = new Relation(); relation.setId(idSequence.nextId()); relation.setCreated(Instant.now()); @@ -230,7 +223,7 @@ public class CompanyService 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()); - relationMap.insert(relation); // todo use transaction! + relationMap.insert(relation); } /** @@ -239,7 +232,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { * @param newStatus WorkflowStatus.Active - при возобналвении; WorkflowStatus.Blocked - при блокировки/расторжении */ private void onChangeWorkflowStatus(Company company, String oldStatus, String newStatus) { - //todo в ТЗ упоминается: ри изменении (relation/put): //из соответствующего параметра полученного метода, если значение отличается от сохраненного ране log.debug("Company id={} status changed from {} to {}", company.getId(), oldStatus, company.getWorkflowStatus()); assert Objects.equals(newStatus, company.getWorkflowStatus()); @@ -267,6 +259,9 @@ public class CompanyService extends QueueConsumer implements InitializingBean { } } + if (WorkflowStatus.Blocked.equalsByKey(newStatus)) { + kafkaSentAccountNotification(company); + } } @@ -289,10 +284,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { log.warn("Company {} not found", request.getId()); return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyNotFound, request.getId()); } -// if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { -// log.trace("Company {} not active: {}", company.getId(), company.getWorkflowStatus()); -// return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyDisabled, request.getId()); -// } company.setUpdated(Instant.now()); @@ -306,11 +297,10 @@ public class CompanyService extends QueueConsumer implements InitializingBean { String prevStatus = company.getWorkflowStatus(); company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); log.debug("Update company.id={}", company.getId()); companyMap.update(company); - // todo kafka send !!! Account. + onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); return null; // Company company = companyMap.getSingleObjectByID(req.getId()); 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 627c7b041..f52d1b24a 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 @@ -15,18 +15,23 @@ import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; +import java.util.Objects; + @Service public class CompanySymbolService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg companySymbolsMap; + private final ImdgId idSequence; @Autowired public CompanySymbolService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider) { super(kafkaQueue, kafkaProducer); this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + this.idSequence = imdgProvider.getImdgIdGenerator(); } @Override @@ -47,4 +52,16 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB companySymbolsMap.update(companySymbols); log.debug("successfully processed, id {}", companySymbols.getId()); } + + public CompanySymbols createCompanySymbol(Long companyId, String companySymbol, String companySymbolValue) { + Objects.requireNonNull(companyId); + CompanySymbols newSymbol = new CompanySymbols(); + newSymbol.setId(idSequence.nextId()); + newSymbol.setCompanyId(companyId); + newSymbol.setCompanySymbol(companySymbol); + newSymbol.setCompanySymbolValue(companySymbolValue); + log.debug("Created new companySymbols.id={} for company {}", newSymbol.getId(), companyId); + companySymbolsMap.insert(newSymbol); + return newSymbol; + } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java index 87476c8e6..66b28a154 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java @@ -7,7 +7,6 @@ public class CompanyNewRequest { private String shortName; @JsonProperty private String fullName; - @JsonProperty private String companySymbol; @JsonProperty @@ -15,7 +14,7 @@ public class CompanyNewRequest { @JsonProperty private String workflowStatus; - // for update, todo разобраться, это тот же тип запроса или надо отдельный на update сделать? + // for update, это поле может использоваться в gateway-api @JsonProperty private Long id; @@ -51,14 +50,6 @@ public class CompanyNewRequest { this.companySymbolValue = companySymbolValue; } - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - public String getWorkflowStatus() { return workflowStatus; } @@ -66,4 +57,12 @@ public class CompanyNewRequest { public void setWorkflowStatus(String workflowStatus) { this.workflowStatus = workflowStatus; } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } } From a6926d1e4686488466e3784b708f0e7fb59d1314 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Wed, 5 Apr 2023 17:03:18 +0300 Subject: [PATCH 46/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F=D0=BB=20=D1=82=D0=B8?= =?UTF-8?q?=D0=BF=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=BE=D0=B2=20?= =?UTF-8?q?=D1=81=20Double=20=D0=BD=D0=B0=20BigDecimal.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../securities/component/ListingBuilder.java | 10 +++++----- .../service/cud/EquitySecurityService.java | 5 ++--- .../cud/FixedIncomeSecurityService.java | 13 ++++++------- .../cud/MoneyMarketSecurityService.java | 9 ++++----- .../service/cud/СurrencyService.java | 5 ++--- .../service/EquitySecurityServiceTest.java | 4 ++-- .../FixedIncomeSecurityServiceTest.java | 12 ++++++------ .../service/MoneyMarketSecurityFactory.java | 12 ++++++------ .../MoneyMarketSecurityServiceTest.java | 6 +++--- .../securitites/EquitySecurityNewRequest.java | 8 +++++--- .../EquitySecurityUpdateRequest.java | 8 +++++--- .../FixedIncomeSecurityNewRequest.java | 19 ++++++++++--------- .../FixedIncomeSecurityUpdateRequest.java | 19 ++++++++++--------- .../MoneyMarketSecurityNewRequest.java | 13 +++++++------ .../MoneyMarketSecurityUpdateRequest.java | 13 +++++++------ 15 files changed, 80 insertions(+), 76 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java index 376c068d2..e8a65395c 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/component/ListingBuilder.java @@ -10,15 +10,14 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSe import ru.spcex.platform.enumeration.Market; import ru.spcex.platform.enumeration.Status; -import java.math.BigDecimal; - public class ListingBuilder { private final String market = Market.mkrs.getKey(); + public Listing byNewMms(MoneyMarketSecurity mms, MoneyMarketSecurityNewRequest mmsReq) { Listing listing = new Listing(); listing.setCreated(mms.getCreated()); listing.setSecurityId(mms.getId()); - listing.setLotSize(BigDecimal.valueOf(mmsReq.getLotSize())); + listing.setLotSize(mmsReq.getLotSize()); listing.setMarket(market); listing.setSymbolCode(mms.getSecuritySymbol()); listing.setSymbolName(mms.getFullName()); @@ -26,6 +25,7 @@ public class ListingBuilder { listing.setWorkflowStatus(Status.Active.getKey()); return listing; } + public Listing byUpdateMms(MoneyMarketSecurity mms, Listing listing) { listing.setSecurityId(mms.getId()); listing.setSymbolCode(mms.getSecuritySymbol()); @@ -41,7 +41,7 @@ public class ListingBuilder { Listing listing = new Listing(); listing.setCreated(equitySecurity.getCreated()); listing.setSecurityId(equitySecurity.getId()); - listing.setLotSize(BigDecimal.valueOf(request.getLotSize())); + listing.setLotSize(request.getLotSize()); listing.setMarket(market); listing.setSymbolCode(equitySecurity.getSecuritySymbol()); listing.setSymbolName(equitySecurity.getFullName()); @@ -65,7 +65,7 @@ public class ListingBuilder { Listing listing = new Listing(); listing.setCreated(instant.getCreated()); listing.setSecurityId(instant.getId()); - listing.setLotSize(BigDecimal.valueOf(request.getLotSize())); + listing.setLotSize(request.getLotSize()); listing.setMarket(market); listing.setSymbolCode(instant.getSecuritySymbol()); listing.setSymbolName(instant.getFullName()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java index e7accd308..5a3585bb8 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java @@ -25,7 +25,6 @@ import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; -import java.math.BigDecimal; import java.time.Instant; import java.util.Map; @@ -85,7 +84,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing equity.setFullName(req.getFullName()); equity.setIsin(req.getIsin()); equity.setShareType(req.getShareType()); - equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setLotSize(req.getLotSize()); equity.setIssuerId(req.getIssuerId()); equity.setShortNameEng(req.getShortNameEng()); equity.setFullNameEng(req.getFullNameEng()); @@ -128,7 +127,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing equity.setFullName(req.getFullName()); equity.setIsin(req.getIsin()); equity.setShareType(req.getShareType()); - equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setLotSize(req.getLotSize()); equity.setIssuerId(req.getIssuerId()); equity.setShortNameEng(req.getShortNameEng()); equity.setFullNameEng(req.getFullNameEng()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java index aa6c36cee..6beb91d3a 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java @@ -25,7 +25,6 @@ import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; -import java.math.BigDecimal; import java.time.Instant; import java.util.Map; @@ -85,11 +84,11 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial fixedIncome.setFullName(req.getFullName()); fixedIncome.setIsin(req.getIsin()); fixedIncome.setBondType(req.getBondType()); - fixedIncome.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); - fixedIncome.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); + fixedIncome.setLotSize(req.getLotSize()); + fixedIncome.setNominalValue(req.getNominalValue()); fixedIncome.setNominalCurrency(req.getNominalCurrency()); fixedIncome.setMaturityDate(req.getMaturityDate()); - fixedIncome.setCoupon(req.getCoupon() != null ? BigDecimal.valueOf(req.getCoupon()) : null); + fixedIncome.setCoupon(req.getCoupon()); fixedIncome.setCouponFrequency(req.getCouponFrequency()); fixedIncome.setIssuerId(req.getIssuerId()); fixedIncome.setShortNameEng(req.getShortNameEng()); @@ -133,11 +132,11 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial fixedIncome.setFullName(req.getFullName()); fixedIncome.setIsin(req.getIsin()); fixedIncome.setBondType(req.getBondType()); - fixedIncome.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); - fixedIncome.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); + fixedIncome.setLotSize(req.getLotSize()); + fixedIncome.setNominalValue(req.getNominalValue()); fixedIncome.setNominalCurrency(req.getNominalCurrency()); fixedIncome.setMaturityDate(req.getMaturityDate()); - fixedIncome.setCoupon(req.getCoupon() != null ? BigDecimal.valueOf(req.getCoupon()) : null); + fixedIncome.setCoupon(req.getCoupon()); fixedIncome.setCouponFrequency(req.getCouponFrequency()); fixedIncome.setIssuerId(req.getIssuerId()); fixedIncome.setShortNameEng(req.getShortNameEng()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java index 383610af8..c96cb0e94 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java @@ -31,7 +31,6 @@ import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; -import java.math.BigDecimal; import java.time.Instant; import java.util.Map; import java.util.Optional; @@ -107,8 +106,8 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setId(idGenerator.nextId()); mms.setStartDate(req.getStartDate()); mms.setEndDate(req.getEndDate()); - mms.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); - mms.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + mms.setNominalValue(req.getNominalValue()); + mms.setLotSize(req.getLotSize()); mms.setNominalCurrency(req.getNominalCurrency()); mms.setInstrumentType(req.getInstrumentType()); mms.setFullName(req.getFullName()); @@ -161,8 +160,8 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setUpdated(updateTime); mms.setStartDate(req.getStartDate()); mms.setEndDate(req.getEndDate()); - mms.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); - mms.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + mms.setNominalValue(req.getNominalValue()); + mms.setLotSize(req.getLotSize()); mms.setNominalCurrency(req.getNominalCurrency()); mms.setInstrumentType(req.getInstrumentType()); mms.setFullName(req.getFullName()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java index 779b46eca..a6632dbe5 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java @@ -25,7 +25,6 @@ import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; -import java.math.BigDecimal; import java.time.Instant; import java.util.Map; @@ -85,7 +84,7 @@ public class СurrencyService extends QueueConsumer implements InitializingBean equity.setFullName(req.getFullName()); equity.setIsin(req.getIsin()); equity.setShareType(req.getShareType()); - equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setLotSize(req.getLotSize()); equity.setIssuerId(req.getIssuerId()); equity.setShortNameEng(req.getShortNameEng()); equity.setFullNameEng(req.getFullNameEng()); @@ -128,7 +127,7 @@ public class СurrencyService extends QueueConsumer implements InitializingBean equity.setFullName(req.getFullName()); equity.setIsin(req.getIsin()); equity.setShareType(req.getShareType()); - equity.setLotSize(req.getLotSize() != null ? BigDecimal.valueOf(req.getLotSize()) : null); + equity.setLotSize(req.getLotSize()); equity.setIssuerId(req.getIssuerId()); equity.setShortNameEng(req.getShortNameEng()); equity.setFullNameEng(req.getFullNameEng()); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java index d34e89aff..c3928cb15 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java @@ -185,7 +185,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ equitySecurityNewRequest.setFullName(equitySecurity.getFullName()); equitySecurityNewRequest.setIsin(equitySecurity.getIsin()); equitySecurityNewRequest.setShareType(equitySecurity.getShareType()); - equitySecurityNewRequest.setLotSize(equitySecurity.getLotSize().doubleValue()); + equitySecurityNewRequest.setLotSize(equitySecurity.getLotSize()); equitySecurityNewRequest.setIssuerId(equitySecurity.getIssuerId()); equitySecurityNewRequest.setShortNameEng(equitySecurity.getShortNameEng()); equitySecurityNewRequest.setFullNameEng(equitySecurity.getFullNameEng()); @@ -202,7 +202,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ equitySecurityUpdateRequest.setFullName(equitySecurity.getFullName()); equitySecurityUpdateRequest.setIsin(equitySecurity.getIsin()); equitySecurityUpdateRequest.setShareType(equitySecurity.getShareType()); - equitySecurityUpdateRequest.setLotSize(equitySecurity.getLotSize().doubleValue()); + equitySecurityUpdateRequest.setLotSize(equitySecurity.getLotSize()); equitySecurityUpdateRequest.setIssuerId(equitySecurity.getIssuerId()); equitySecurityUpdateRequest.setShortNameEng(equitySecurity.getShortNameEng()); equitySecurityUpdateRequest.setFullNameEng(equitySecurity.getFullNameEng()); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java index 92ae716b9..1c4fe140b 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java @@ -194,11 +194,11 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ fixedIncomeSecurityNewRequest.setFullName(fixedIncomeSecurity.getFullName()); fixedIncomeSecurityNewRequest.setIsin(fixedIncomeSecurity.getIsin()); fixedIncomeSecurityNewRequest.setBondType(fixedIncomeSecurity.getBondType()); - fixedIncomeSecurityNewRequest.setLotSize(fixedIncomeSecurity.getLotSize().doubleValue()); - fixedIncomeSecurityNewRequest.setNominalValue(fixedIncomeSecurity.getNominalValue().doubleValue()); + fixedIncomeSecurityNewRequest.setLotSize(fixedIncomeSecurity.getLotSize()); + fixedIncomeSecurityNewRequest.setNominalValue(fixedIncomeSecurity.getNominalValue()); fixedIncomeSecurityNewRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); fixedIncomeSecurityNewRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); - fixedIncomeSecurityNewRequest.setCoupon(fixedIncomeSecurity.getCoupon().doubleValue()); + fixedIncomeSecurityNewRequest.setCoupon(fixedIncomeSecurity.getCoupon()); fixedIncomeSecurityNewRequest.setCouponFrequency(fixedIncomeSecurity.getCouponFrequency()); fixedIncomeSecurityNewRequest.setIssuerId(fixedIncomeSecurity.getIssuerId()); fixedIncomeSecurityNewRequest.setShortNameEng(fixedIncomeSecurity.getShortNameEng()); @@ -216,11 +216,11 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ equitySecurityUpdateRequest.setFullName(fixedIncomeSecurity.getFullName()); equitySecurityUpdateRequest.setIsin(fixedIncomeSecurity.getIsin()); equitySecurityUpdateRequest.setBondType(fixedIncomeSecurity.getBondType()); - equitySecurityUpdateRequest.setLotSize(fixedIncomeSecurity.getLotSize().doubleValue()); - equitySecurityUpdateRequest.setNominalValue(fixedIncomeSecurity.getNominalValue().doubleValue()); + equitySecurityUpdateRequest.setLotSize(fixedIncomeSecurity.getLotSize()); + equitySecurityUpdateRequest.setNominalValue(fixedIncomeSecurity.getNominalValue()); equitySecurityUpdateRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); equitySecurityUpdateRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); - equitySecurityUpdateRequest.setCoupon(fixedIncomeSecurity.getCoupon().doubleValue()); + equitySecurityUpdateRequest.setCoupon(fixedIncomeSecurity.getCoupon()); equitySecurityUpdateRequest.setCouponFrequency(fixedIncomeSecurity.getCouponFrequency()); equitySecurityUpdateRequest.setIssuerId(fixedIncomeSecurity.getIssuerId()); equitySecurityUpdateRequest.setShortNameEng(fixedIncomeSecurity.getShortNameEng()); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java index 0ccfd0d7e..d90f48819 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityFactory.java @@ -16,10 +16,10 @@ class MoneyMarketSecurityFactory { private Long id = 0L; private Long securityId = 0L;// (linked to security) private String description = "tsetse"; - private Double lotSize = 1.0; + private BigDecimal lotSize = BigDecimal.valueOf(341.0); private LocalDate startDate = LocalDate.ofEpochDay(0); private LocalDate endDate = LocalDate.now(); - private BigDecimal nominalValue = BigDecimal.valueOf(1.0); + private BigDecimal nominalValue = BigDecimal.valueOf(11.0); private String instrumentType = RATE; // (linked to instrumentType) private String fullName = "estat"; private String shortName = "esasdftat"; @@ -31,7 +31,7 @@ class MoneyMarketSecurityFactory { return fullName; } - public MoneyMarketSecurityFactory setLotSize(Double lotSize) { + public MoneyMarketSecurityFactory setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; return this; } @@ -104,7 +104,7 @@ class MoneyMarketSecurityFactory { moneyMarketSecurity.setTermType(termType); moneyMarketSecurity.setIssuerId(issuerId); moneyMarketSecurity.setDescription(description); - moneyMarketSecurity.setLotSize(BigDecimal.valueOf(lotSize)); + moneyMarketSecurity.setLotSize(lotSize); moneyMarketSecurity.setSecuritySymbol(securitySymbol); moneyMarketSecurity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); @@ -119,7 +119,7 @@ class MoneyMarketSecurityFactory { moneyMarketSecurityUpdateRequest.setLotSize(lotSize); moneyMarketSecurityUpdateRequest.setStartDate(startDate); moneyMarketSecurityUpdateRequest.setEndDate(endDate); - moneyMarketSecurityUpdateRequest.setNominalValue(nominalValue.doubleValue()); + moneyMarketSecurityUpdateRequest.setNominalValue(nominalValue); moneyMarketSecurityUpdateRequest.setNominalCurrency(nominalCurrency); moneyMarketSecurityUpdateRequest.setInstrumentType(instrumentType); moneyMarketSecurityUpdateRequest.setFullName(fullName); @@ -148,7 +148,7 @@ class MoneyMarketSecurityFactory { keyRequest.setLotSize(lotSize); keyRequest.setStartDate(startDate); keyRequest.setEndDate(endDate); - keyRequest.setNominalValue(nominalValue.doubleValue()); + keyRequest.setNominalValue(nominalValue); keyRequest.setNominalCurrency(nominalCurrency); keyRequest.setInstrumentType(instrumentType); keyRequest.setFullName(fullName); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java index 5331b7e6f..e5ddda98b 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java @@ -141,14 +141,14 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{ clearAllInImdg(moneyMarketSecurityMap); final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE; String updateTermType = "updateTermType"; - Double updateLotSize = 112.0; + BigDecimal updateLotSize = BigDecimal.valueOf(112.0); final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory .getMoneyMarketSecurity(); moneyMarketSecurityPrediction.setTermType(updateTermType); moneyMarketSecurityMap.insert(moneyMarketSecurityPrediction); moneyMarketSecurityPrediction.setTermType(termType); - moneyMarketSecurityPrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); + moneyMarketSecurityPrediction.setLotSize(updateLotSize); final MoneyMarketSecurityUpdateRequest keyRequest = moneyMarketSecurityFactory .getMoneyMarketSecurityUpdateRequest(); keyRequest.setTermType(termType); @@ -156,7 +156,7 @@ public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{ Listing listingPrediction = new Listing(); listingPrediction = listingBuilder.byUpdateMms(moneyMarketSecurityPrediction, listingPrediction); listingImdg.insert(listingPrediction); - listingPrediction.setLotSize(BigDecimal.valueOf(updateLotSize)); + listingPrediction.setLotSize(updateLotSize); //ACT String jsonString = getJsonStringForUPDATE(keyRequest, ID); diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java index 909618598..051273278 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; +import java.math.BigDecimal; + public class EquitySecurityNewRequest implements WithSecuritySymbol, WithInstrumentType { @JsonProperty public String securitySymbol; @@ -16,7 +18,7 @@ public class EquitySecurityNewRequest implements WithSecuritySymbol, WithInstrum @JsonProperty public String shareType; @JsonProperty - public Double lotSize; + public BigDecimal lotSize; @JsonProperty public Long issuerId; @JsonProperty @@ -69,11 +71,11 @@ public class EquitySecurityNewRequest implements WithSecuritySymbol, WithInstrum this.shareType = shareType; } - public Double getLotSize() { + public BigDecimal getLotSize() { return lotSize; } - public void setLotSize(Double lotSize) { + public void setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java index fb4806e79..10a42dabc 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java @@ -5,6 +5,8 @@ import ru.spcex.platform.classes.base.interfaces.WithId; import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; +import java.math.BigDecimal; + public class EquitySecurityUpdateRequest implements WithId, WithInstrumentType, WithWorkflowStatus { @JsonProperty public Long id; @@ -19,7 +21,7 @@ public class EquitySecurityUpdateRequest implements WithId, WithInstrumentType, @JsonProperty public String shareType; @JsonProperty - public Double lotSize; + public BigDecimal lotSize; @JsonProperty public Long issuerId; @JsonProperty @@ -80,11 +82,11 @@ public class EquitySecurityUpdateRequest implements WithId, WithInstrumentType, this.shareType = shareType; } - public Double getLotSize() { + public BigDecimal getLotSize() { return lotSize; } - public void setLotSize(Double lotSize) { + public void setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java index c39fcb494..6d0112883 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java @@ -8,6 +8,7 @@ import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSeria import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; +import java.math.BigDecimal; import java.time.LocalDate; public class FixedIncomeSecurityNewRequest implements WithSecuritySymbol, WithInstrumentType { @@ -22,9 +23,9 @@ public class FixedIncomeSecurityNewRequest implements WithSecuritySymbol, WithIn @JsonProperty public String bondType; @JsonProperty - public Double lotSize; + public BigDecimal lotSize; @JsonProperty - public Double nominalValue; + public BigDecimal nominalValue; @JsonProperty public String nominalCurrency; @JsonProperty @@ -32,7 +33,7 @@ public class FixedIncomeSecurityNewRequest implements WithSecuritySymbol, WithIn @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate maturityDate; @JsonProperty - public Double coupon; + public BigDecimal coupon; @JsonProperty public Long couponFrequency; @JsonProperty @@ -87,19 +88,19 @@ public class FixedIncomeSecurityNewRequest implements WithSecuritySymbol, WithIn this.bondType = bondType; } - public Double getLotSize() { + public BigDecimal getLotSize() { return lotSize; } - public void setLotSize(Double lotSize) { + public void setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; } - public Double getNominalValue() { + public BigDecimal getNominalValue() { return nominalValue; } - public void setNominalValue(Double nominalValue) { + public void setNominalValue(BigDecimal nominalValue) { this.nominalValue = nominalValue; } @@ -119,11 +120,11 @@ public class FixedIncomeSecurityNewRequest implements WithSecuritySymbol, WithIn this.maturityDate = maturityDate; } - public Double getCoupon() { + public BigDecimal getCoupon() { return coupon; } - public void setCoupon(Double coupon) { + public void setCoupon(BigDecimal coupon) { this.coupon = coupon; } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java index dcfd798ea..592582ab6 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java @@ -9,6 +9,7 @@ import ru.spcex.platform.classes.base.interfaces.WithId; import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.classes.base.interfaces.WithWorkflowStatus; +import java.math.BigDecimal; import java.time.LocalDate; public class FixedIncomeSecurityUpdateRequest implements WithId, WithInstrumentType, WithWorkflowStatus { @@ -25,9 +26,9 @@ public class FixedIncomeSecurityUpdateRequest implements WithId, WithInstrumentT @JsonProperty public String bondType; @JsonProperty - public Double lotSize; + public BigDecimal lotSize; @JsonProperty - public Double nominalValue; + public BigDecimal nominalValue; @JsonProperty public String nominalCurrency; @JsonProperty @@ -35,7 +36,7 @@ public class FixedIncomeSecurityUpdateRequest implements WithId, WithInstrumentT @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate maturityDate; @JsonProperty - public Double coupon; + public BigDecimal coupon; @JsonProperty public Long couponFrequency; @JsonProperty @@ -98,19 +99,19 @@ public class FixedIncomeSecurityUpdateRequest implements WithId, WithInstrumentT this.bondType = bondType; } - public Double getLotSize() { + public BigDecimal getLotSize() { return lotSize; } - public void setLotSize(Double lotSize) { + public void setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; } - public Double getNominalValue() { + public BigDecimal getNominalValue() { return nominalValue; } - public void setNominalValue(Double nominalValue) { + public void setNominalValue(BigDecimal nominalValue) { this.nominalValue = nominalValue; } @@ -130,11 +131,11 @@ public class FixedIncomeSecurityUpdateRequest implements WithId, WithInstrumentT this.maturityDate = maturityDate; } - public Double getCoupon() { + public BigDecimal getCoupon() { return coupon; } - public void setCoupon(Double coupon) { + public void setCoupon(BigDecimal coupon) { this.coupon = coupon; } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java index 44466ac0f..108085f5f 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityNewRequest.java @@ -10,6 +10,7 @@ import ru.spcex.platform.classes.base.interfaces.WithInstrumentType; import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; import ru.spcex.platform.classes.base.interfaces.WithStartDt; +import java.math.BigDecimal; import java.time.LocalDate; public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt, WithSecuritySymbol, WithInstrumentType { @@ -22,7 +23,7 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt, Wi @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate endDate; @JsonProperty - public Double nominalValue; + public BigDecimal nominalValue; @JsonProperty public String nominalCurrency; @JsonProperty @@ -38,7 +39,7 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt, Wi @JsonProperty public String securitySymbol; @JsonProperty - public Double lotSize; + public BigDecimal lotSize; @JsonProperty public String termType; @JsonProperty @@ -66,11 +67,11 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt, Wi this.endDate = endDate; } - public Double getNominalValue() { + public BigDecimal getNominalValue() { return nominalValue; } - public void setNominalValue(Double nominalValue) { + public void setNominalValue(BigDecimal nominalValue) { this.nominalValue = nominalValue; } @@ -114,11 +115,11 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt, Wi this.securitySymbol = securitySymbol; } - public Double getLotSize() { + public BigDecimal getLotSize() { return lotSize; } - public void setLotSize(Double lotSize) { + public void setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java index 9778597b7..1f743aca4 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/MoneyMarketSecurityUpdateRequest.java @@ -8,6 +8,7 @@ import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDes import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; import ru.spcex.platform.classes.base.interfaces.*; +import java.math.BigDecimal; import java.time.LocalDate; public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, WithEndDt, WithInstrumentType, WithWorkflowStatus { @@ -24,7 +25,7 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi @JsonProperty public LocalDate endDate; @JsonProperty - public Double nominalValue; + public BigDecimal nominalValue; @JsonProperty public String nominalCurrency; @JsonProperty @@ -40,7 +41,7 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi @JsonProperty public String securitySymbol; @JsonProperty - public Double lotSize; + public BigDecimal lotSize; @JsonProperty public String termType; @JsonProperty @@ -68,11 +69,11 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi this.endDate = endDate; } - public Double getNominalValue() { + public BigDecimal getNominalValue() { return nominalValue; } - public void setNominalValue(Double nominalValue) { + public void setNominalValue(BigDecimal nominalValue) { this.nominalValue = nominalValue; } @@ -173,11 +174,11 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi this.workflowStatus = workflowStatus; } - public Double getLotSize() { + public BigDecimal getLotSize() { return lotSize; } - public void setLotSize(Double lotSize) { + public void setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; } From 15404dbec1fda31ec7889c646f6f323f477d75bb Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 5 Apr 2023 17:23:16 +0300 Subject: [PATCH 47/90] contact meta fix --- clearing-parent/backend-api/src/main/resources/meta/meta.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index 7f4155354..640e1b1ef 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -385,11 +385,6 @@ - - - - - From 894f12591d8ce462e0a76c5e243b9faf01b9e411 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 5 Apr 2023 17:25:16 +0300 Subject: [PATCH 48/90] FixedIncomeCashFlowNewRequest, FixedIncomeCashFlowUpdateRequest --- .../FixedIncomeCashFlowNewRequest.java | 70 ++++++++++++++++ .../FixedIncomeCashFlowUpdateRequest.java | 82 +++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java new file mode 100644 index 000000000..eaca2e32b --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java @@ -0,0 +1,70 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; +import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; + +import java.math.BigDecimal; +import java.time.LocalDate; + +public class FixedIncomeCashFlowNewRequest implements WithSecuritySymbol { + @JsonProperty + public String securitySymbol; + + @JsonProperty + @JsonDeserialize(using = NumberDeserializers.BigDecimalDeserializer.class) + public BigDecimal accruedCoupon; + + @JsonProperty + @JsonDeserialize(using = NumberDeserializers.BigDecimalDeserializer.class) + public BigDecimal nominalValue; + + @JsonProperty + public Long number; + + @JsonProperty + public LocalDate valueDate; + + + @Override + public String getSecuritySymbol() { + return securitySymbol; + } + + public void setSecuritySymbol(String securitySymbol) { + this.securitySymbol = securitySymbol; + } + + public BigDecimal getAccruedCoupon() { + return accruedCoupon; + } + + public void setAccruedCoupon(BigDecimal accruedCoupon) { + this.accruedCoupon = accruedCoupon; + } + + public BigDecimal getNominalValue() { + return nominalValue; + } + + public void setNominalValue(BigDecimal nominalValue) { + this.nominalValue = nominalValue; + } + + public Long getNumber() { + return number; + } + + public void setNumber(Long number) { + this.number = number; + } + + public LocalDate getValueDate() { + return valueDate; + } + + public void setValueDate(LocalDate valueDate) { + this.valueDate = valueDate; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java new file mode 100644 index 000000000..e5d1c2d50 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java @@ -0,0 +1,82 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; +import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; + +import java.math.BigDecimal; +import java.time.LocalDate; + +public class FixedIncomeCashFlowUpdateRequest implements WithSecuritySymbol { + @JsonProperty + public Long id; + + @JsonProperty + public String securitySymbol; + + @JsonProperty + @JsonDeserialize(using = NumberDeserializers.BigDecimalDeserializer.class) + public BigDecimal accruedCoupon; + + @JsonProperty + @JsonDeserialize(using = NumberDeserializers.BigDecimalDeserializer.class) + public BigDecimal nominalValue; + + @JsonProperty + public Long number; + + @JsonProperty + public LocalDate valueDate; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @Override + public String getSecuritySymbol() { + return securitySymbol; + } + + public void setSecuritySymbol(String securitySymbol) { + this.securitySymbol = securitySymbol; + } + + public BigDecimal getAccruedCoupon() { + return accruedCoupon; + } + + public void setAccruedCoupon(BigDecimal accruedCoupon) { + this.accruedCoupon = accruedCoupon; + } + + public BigDecimal getNominalValue() { + return nominalValue; + } + + public void setNominalValue(BigDecimal nominalValue) { + this.nominalValue = nominalValue; + } + + public Long getNumber() { + return number; + } + + public void setNumber(Long number) { + this.number = number; + } + + public LocalDate getValueDate() { + return valueDate; + } + + public void setValueDate(LocalDate valueDate) { + this.valueDate = valueDate; + } + +} From 15a477e8ce9accdcbe1ba48365fbf290401eeb56 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Wed, 5 Apr 2023 18:45:29 +0300 Subject: [PATCH 49/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20CurrencyService?= =?UTF-8?q?=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D1=8E=20?= =?UTF-8?q?=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BA=20=D0=BD=D0=B5?= =?UTF-8?q?=D0=BC=D1=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../securities/errors/SecuritiesError.java | 5 +- .../service/cud/CurrencyService.java | 92 ++++++++++ .../cud/FixedIncomeSecurityService.java | 6 +- .../service/cud/СurrencyService.java | 171 ------------------ .../validation/ValidationProvider.java | 24 +++ .../rule/CurrencyNewValidationRule.java | 38 ++++ .../rule/CurrencyUpdateValidationRule.java | 38 ++++ .../service/AbstractServiceTest.java | 5 + .../service/CurrencyServiceTest.java | 95 ++++++++++ .../service/EquitySecurityServiceTest.java | 48 ++--- .../FixedIncomeSecurityServiceTest.java | 48 ++--- .../cud/securitites/CurrencyNewRequest.java | 26 +++ .../securitites/CurrencyUpdateRequest.java | 39 ++++ 13 files changed, 398 insertions(+), 237 deletions(-) create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java delete mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyNewValidationRule.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyUpdateValidationRule.java create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyNewRequest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyUpdateRequest.java diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java index 0981c30ff..7bffa0a3f 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java @@ -6,8 +6,11 @@ public enum SecuritiesError implements IErrorEnumId { RequiredFieldIsEmpty(1002L), WrongFieldValue(1004L), InstrumentAlreadyExists(1010L), - InstrumentNotActive(1012L), InstrumentNotFound(1011L), + InstrumentNotActive(1012L), + CurrencyAlreadyExists(1015L), + CurrencyNotFound(1016L), + ; private final Long id; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java new file mode 100644 index 000000000..52e01c60f --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java @@ -0,0 +1,92 @@ +package ru.spcex.clearing.securities.service.cud; + +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.misc.Currency; +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.securitites.CurrencyNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.securities.component.ListingBuilder; +import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.ImdgTransaction; + +@Service +public class CurrencyService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg currencyImdg; + private final ImdgProvider imdgProvider; + private final ImdgId idGenerator; + private final ValidationProvider validation; + private final ValidationHelper validationHelper; + private final ListingBuilder listingBuilder = new ListingBuilder(); + + @Autowired + public CurrencyService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationProvider validation, + ValidationHelper validationHelper) { + super(kafkaQueue, kafkaProducer); + this.validation = validation; + this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class); + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.validationHelper = validationHelper; + } + + @Override + public void afterPropertiesSet() { + callback(CurrencyNewRequest.class) + .setFunction(this::newCurrency) + .forDestination(Consts.DESTINATION_СURRENCY_NEW, callbacks::put); + callback(CurrencyUpdateRequest.class) + .setFunction(this::updateCurrency) + .forDestination(Consts.DESTINATION_СURRENCY_UPDATE, callbacks::put); + imdgProvider.waitAvailable(); + init(); + } + + private RequestInfoUpdate newCurrency(BaseRequest userRequest) { + ImdgTransaction transaction = imdgProvider.newTransaction(); + CurrencyNewRequest req = userRequest.getRequestPayload(); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.currencyNewValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + log.debug("newCurrency received"); + Currency currency = new Currency(); + currency.setId(idGenerator.nextId()); + currency.setCountryCode(req.getCountryCode()); + currency.setCurrencyCode(req.getCurrencyCode()); + currencyImdg.insert(currency); + log.debug("successfully processed, request id {}, new object id {}", userRequest.getId(), currency.getId()); + return null; // default success + } + + private RequestInfoUpdate updateCurrency(BaseRequest userRequest) { + CurrencyUpdateRequest req = userRequest.getRequestPayload(); + log.debug("updateCurrency received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.currencyUpdateValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + Currency currency = currencyImdg.getSingleObjectByID(req.getId()); + currency.setCountryCode(req.getCountryCode()); + currency.setCurrencyCode(req.getCurrencyCode()); + currencyImdg.update(currency); + return null; + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java index 6beb91d3a..aa618aefa 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java @@ -76,7 +76,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeNewValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; - log.debug("EquitySecurityNewRequest received"); + log.debug("newFixedIncome received"); FixedIncomeSecurity fixedIncome = new FixedIncomeSecurity(); fixedIncome.setId(idGenerator.nextId()); fixedIncome.setSecuritySymbol(req.getSecuritySymbol()); @@ -119,7 +119,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial private RequestInfoUpdate updateFixedIncome(BaseRequest userRequest) { FixedIncomeSecurityUpdateRequest req = userRequest.getRequestPayload(); - log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId()); + log.debug("updateFixedIncome received id = {}", req.getId()); RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeUpdateValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; @@ -148,7 +148,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial fixedIncomeSecurityImdg.update(fixedIncome); Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncome.getId())); if (listing == null) { - log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId()); + log.error("updateFixedIncome id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId()); return null; } listing = listingBuilder.byFixedIncomeEquity(fixedIncome, listing); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java deleted file mode 100644 index a6632dbe5..000000000 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/СurrencyService.java +++ /dev/null @@ -1,171 +0,0 @@ -package ru.spcex.clearing.securities.service.cud; - -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.producer.Producer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; -import ru.clearing.classes.statics.data.misc.Listing; -import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.platform.messaging.domain.BaseRequest; -import ru.spcex.clearing.platform.messaging.domain.Consts; -import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; -import ru.spcex.clearing.platform.messaging.service.QueueConsumer; -import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; -import ru.spcex.clearing.securities.component.ListingBuilder; -import ru.spcex.clearing.securities.validation.ValidationProvider; -import ru.spcex.clearing.validation.common.ValidationHelper; -import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.api.ImdgId; -import ru.spcex.platform.imdg.api.ImdgProvider; -import ru.spcex.platform.imdg.api.ImdgTransaction; - -import java.time.Instant; -import java.util.Map; - -@Service -public class СurrencyService extends QueueConsumer implements InitializingBean { - private final Logger log = LoggerFactory.getLogger(getClass()); - private final Imdg equitySecurityImdg; - private final Imdg listingImdg; - private final ImdgProvider imdgProvider; - private final ImdgId idGenerator; - private final ValidationProvider validation; - private final ValidationHelper validationHelper; - private final ListingBuilder listingBuilder = new ListingBuilder(); - - @Autowired - public СurrencyService(Consumer kafkaQueue, - Producer kafkaProducer, - ImdgProvider imdgProvider, - ValidationProvider validation, - ValidationHelper validationHelper) { - super(kafkaQueue, kafkaProducer); - this.validation = validation; - this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); - this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); - this.imdgProvider = imdgProvider; - this.idGenerator = imdgProvider.getImdgIdGenerator(); - this.validationHelper = validationHelper; - } - - @Override - public void afterPropertiesSet() { - callback(EquitySecurityNewRequest.class) - .setFunction(this::newEquity) - .forDestination(Consts.DESTINATION_СURRENCY_NEW, callbacks::put); - callback(EquitySecurityUpdateRequest.class) - .setFunction(this::updateEquity) - .forDestination(Consts.DESTINATION_СURRENCY_UPDATE, callbacks::put); - callback(CommonDeleteRequest.class) - .setFunction(this::deleteEquity) - .forDestination(Consts.DESTINATION_СURRENCY_DELETE, callbacks::put); - imdgProvider.waitAvailable(); - init(); - } - - private RequestInfoUpdate newEquity(BaseRequest userRequest) { - ImdgTransaction transaction = imdgProvider.newTransaction(); - EquitySecurityNewRequest req = userRequest.getRequestPayload(); - - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityNewValidator()); - if (requestInfoUpdate != null) return requestInfoUpdate; - - log.debug("EquitySecurityNewRequest received"); - EquitySecurity equity = new EquitySecurity(); - equity.setId(idGenerator.nextId()); - equity.setSecuritySymbol(req.getSecuritySymbol()); - equity.setShortName(req.getShortName()); - equity.setFullName(req.getFullName()); - equity.setIsin(req.getIsin()); - equity.setShareType(req.getShareType()); - equity.setLotSize(req.getLotSize()); - equity.setIssuerId(req.getIssuerId()); - equity.setShortNameEng(req.getShortNameEng()); - equity.setFullNameEng(req.getFullNameEng()); - equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); - equity.setInstrumentType(req.getInstrumentType()); - equity.setSecurityId(equity.getId()); - equity.setCreated(Instant.now()); - try { - transaction.beginTransaction(); - Imdg equityImdg = transaction.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); - Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); - //одним скопом выполняем реквест - equityImdg.insert(equity); - Listing listing = listingBuilder.byNewEquity(equity, req); - listingMap.insert(listing); - //и сохраняем обновленный -// reqInfoMap.insert(reqInfo); - transaction.commitTransaction(); - } catch (Throwable e) { - transaction.rollbackTransaction(); -// RequestInfo.update(reqInfo, Status.Error, ExceptionUtils.getStackTrace(e)); -// requestInfoImdg.insert(reqInfo); - } - log.debug("successfully processed, request id {}, new object id {}", userRequest.getId(), equity.getId()); - return null; // default success - } - - private RequestInfoUpdate updateEquity(BaseRequest userRequest) { - EquitySecurityUpdateRequest req = userRequest.getRequestPayload(); - log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId()); - - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityUpdateValidator()); - if (requestInfoUpdate != null) return requestInfoUpdate; - - EquitySecurity equity = equitySecurityImdg.getSingleObjectByID(req.getId()); - Instant updateTime = Instant.now(); - equity.setUpdated(updateTime); - equity.setSecuritySymbol(req.getSecuritySymbol()); - equity.setShortName(req.getShortName()); - equity.setFullName(req.getFullName()); - equity.setIsin(req.getIsin()); - equity.setShareType(req.getShareType()); - equity.setLotSize(req.getLotSize()); - equity.setIssuerId(req.getIssuerId()); - equity.setShortNameEng(req.getShortNameEng()); - equity.setFullNameEng(req.getFullNameEng()); - equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); - equity.setInstrumentType(req.getInstrumentType()); - - equitySecurityImdg.update(equity); - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); - if (listing == null) { - log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); - return null; - } - listing = listingBuilder.byUpdateEquity(equity, listing); - listingImdg.update(listing); - return null; - } - - private RequestInfoUpdate deleteEquity(BaseRequest userRequest) { - CommonDeleteRequest req = userRequest.getRequestPayload(); - log.debug("CommonDeleteRequest received id = {}", req.getId()); - - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityDeleteValidator()); - if (requestInfoUpdate != null) return requestInfoUpdate; - - Instant updateTime = Instant.now(); - EquitySecurity equity = equitySecurityImdg.getSingleObjectByID(req.getId()); - equity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); - equity.setUpdated(updateTime); - equitySecurityImdg.update(equity); - - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); - if (listing == null) { - log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); - return null; - } - listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); - listing.setUpdated(updateTime); - listingImdg.update(listing); - return null; - } -} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index ae176fd6a..ed7c2f5a5 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -28,6 +28,7 @@ public class ValidationProvider { private final Imdg shareTypeDictionaryImdg; private final Imdg bondTypeDictionaryImdg; private final Imdg companyImdg; + private final Imdg currencyImdg; public ValidationProvider(ImdgProvider imdgProvider) { @@ -41,6 +42,7 @@ public class ValidationProvider { this.shareTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ShareTypeDictionary, SpcexObjectBase.class); this.bondTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BondTypeDictionary, SpcexObjectBase.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, SpcexObjectBase.class); + this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, SpcexObjectBase.class); } public Function mmsNewValidator() { @@ -217,4 +219,26 @@ public class ValidationProvider { ); }; } + + public Function currencyNewValidator() { + return currencyRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(currencyRequest); + context.addImdg(IMDGDistributedNames.Map_Currency, currencyImdg); + return new ValidatorImpl<>(context, + CurrencyNewValidationRule.CurrencyNotExists + ); + }; + } + + public Function currencyUpdateValidator() { + return currencyRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(currencyRequest); + context.addImdg(IMDGDistributedNames.Map_Currency, currencyImdg); + return new ValidatorImpl<>(context, + CurrencyUpdateValidationRule.CurrencyExists + ); + }; + } } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyNewValidationRule.java new file mode 100644 index 000000000..d0ea059eb --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyNewValidationRule.java @@ -0,0 +1,38 @@ +package ru.spcex.clearing.securities.validation.rule; + +import org.springframework.util.StringUtils; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyNewRequest; +import ru.spcex.clearing.securities.errors.SecuritiesError; +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.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Map; +import java.util.Optional; + +public enum CurrencyNewValidationRule implements IValidationRule> { + CurrencyNotExists() { + @Override + public Optional validate(ImdgValidationContext context) { + CurrencyNewRequest action = context.getValidatedObject(); + if (!StringUtils.hasText(action.getCurrencyCode())) { + return of(SecuritiesError.RequiredFieldIsEmpty, "currencyCode"); + } + Imdg imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_Currency, SpcexObjectBase.class); + SpcexObjectBase currency = imdgDictionary.getSingleObjectByFieldValues(Map.of( + "currencyCode", action.getCurrencyCode())); + if (currency != null) { + return of(SecuritiesError.CurrencyAlreadyExists, "currencyCode"); + } + return empty(); + } + }; + + @Override + public String ruleName() { + return "MmsNewValidationRule." + name(); + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyUpdateValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyUpdateValidationRule.java new file mode 100644 index 000000000..c54d9b4ae --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CurrencyUpdateValidationRule.java @@ -0,0 +1,38 @@ +package ru.spcex.clearing.securities.validation.rule; + +import org.springframework.util.StringUtils; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyUpdateRequest; +import ru.spcex.clearing.securities.errors.SecuritiesError; +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.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Map; +import java.util.Optional; + +public enum CurrencyUpdateValidationRule implements IValidationRule> { + CurrencyExists() { + @Override + public Optional validate(ImdgValidationContext context) { + CurrencyUpdateRequest action = context.getValidatedObject(); + if (!StringUtils.hasText(action.getCurrencyCode())) { + return of(SecuritiesError.RequiredFieldIsEmpty, "currencyCode"); + } + Imdg imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_Currency, SpcexObjectBase.class); + SpcexObjectBase currency = imdgDictionary.getSingleObjectByFieldValues(Map.of( + "currencyCode", action.getCurrencyCode())); + if (currency == null) { + return of(SecuritiesError.CurrencyNotFound, "currencyCode"); + } + return empty(); + } + }; + + @Override + public String ruleName() { + return "MmsNewValidationRule." + name(); + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java index 86bc623f9..4d9943720 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -13,6 +13,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; +import ru.clearing.classes.statics.data.misc.Currency; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; import ru.clearing.platform.dictionary.*; @@ -22,6 +23,7 @@ import ru.spcex.clearing.securities.config.ErrorResolverConfig; import ru.spcex.clearing.securities.config.ImdgTestConfig; import ru.spcex.clearing.securities.config.KafkaTestConfig; import ru.spcex.clearing.securities.config.ValidationConfig; +import ru.spcex.clearing.securities.service.cud.CurrencyService; import ru.spcex.clearing.securities.service.cud.EquitySecurityService; import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; @@ -42,6 +44,7 @@ import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFie EquitySecurityService.class, FixedIncomeSecurityService.class, MoneyMarketSecurityService.class, + CurrencyService.class, ImdgTestConfig.class, KafkaTestConfig.class, ValidationProvider.class, @@ -61,6 +64,7 @@ public abstract class AbstractServiceTest { protected Imdg shareTypeDictionaryImdg; protected Imdg bondTypeDictionaryImdg; protected Imdg companyImdg; + protected Imdg currencyImdg; public static String RATE = "RATE"; protected String EQTY = "EQTY"; @@ -92,6 +96,7 @@ public abstract class AbstractServiceTest { this.shareTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ShareTypeDictionary, ShareTypeDictionary.class); this.bondTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BondTypeDictionary, BondTypeDictionary.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class); InstrumentTypeDictionary instrumentTypeDictionary = new InstrumentTypeDictionary(); instrumentTypeDictionary.setId(1L); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java new file mode 100644 index 000000000..b52eeac72 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java @@ -0,0 +1,95 @@ +package ru.spcex.clearing.securities.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import ru.clearing.classes.statics.data.misc.Currency; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyUpdateRequest; +import ru.spcex.clearing.securities.service.cud.CurrencyService; +import ru.spcex.clearing.securities.utils.MatcherFactory; + +import javax.annotation.PostConstruct; + +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.securities.utils.TestUtils.*; + +public class CurrencyServiceTest extends AbstractServiceTest { + private static final MatcherFactory.Matcher CURRENCY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + private final long ID = currentId.getAndIncrement(); + private final int PARTITION = 0; + private final String countryCode = "countryCode"; + private final String currencyCode = "currencyCode"; + @Autowired + private CurrencyService currencyService; + + @PostConstruct + protected void init() { + super.init(); + } + + /** + * {@link CurrencyService#newCurrency(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link Currency} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CurrencyNewRequest}:
+ */ + @Test + public void testNewCurrency() { + clearAllInImdg(currencyImdg); + final String TOPIC = Consts.DESTINATION_СURRENCY_NEW; + + final Currency currencyPrediction = new Currency(); + currencyPrediction.setCountryCode(countryCode); + currencyPrediction.setCurrencyCode(currencyCode); + final CurrencyNewRequest request = new CurrencyNewRequest(); + request.setCountryCode(countryCode); + request.setCurrencyCode(currencyCode); + + //ACT + String jsonString = getJsonStringForNew(request, ID); + + addRecordToKafka((MockConsumer) currencyService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + Currency result = currencyImdg.getSingleObjectBySQL(String.format("countryCode = %s", currencyPrediction.getCountryCode())); + currencyPrediction.setId(result.getId()); + CURRENCY_MATCHER.assertMatch(result, currencyPrediction); + } + + /** + * {@link CurrencyService#updateCurrency(BaseRequest)} + * Тест проверяет обновление сущности {@link Currency} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CurrencyUpdateRequest}:
+ */ + @Test + public void testUpdateCurrency() { + clearAllInImdg(currencyImdg); + final String TOPIC = Consts.DESTINATION_СURRENCY_UPDATE; + final Currency currencyPrediction = new Currency(); + currencyPrediction.setId(ID); + currencyPrediction.setCountryCode("ExistsCountryCode"); + currencyPrediction.setCurrencyCode(currencyCode); + currencyImdg.insert(currencyPrediction); + currencyPrediction.setCountryCode(countryCode); + final CurrencyUpdateRequest request = new CurrencyUpdateRequest(); + request.setId(ID); + request.setCountryCode(countryCode); + request.setCurrencyCode(currencyCode); + + //ACT + String jsonString = getJsonStringForUPDATE(request, ID); + + addRecordToKafka((MockConsumer) currencyService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + Currency result = currencyImdg.getSingleObjectBySQL(String.format("countryCode = %s", currencyPrediction.getCountryCode())); + currencyPrediction.setId(result.getId()); + CURRENCY_MATCHER.assertMatch(result, currencyPrediction); + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java index c3928cb15..ffd9b4355 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java @@ -5,16 +5,12 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.misc.Listing; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; import ru.spcex.clearing.securities.service.cud.EquitySecurityService; -import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; import ru.spcex.clearing.securities.utils.MatcherFactory; import javax.annotation.PostConstruct; @@ -24,31 +20,25 @@ import java.util.Map; import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.securities.utils.TestUtils.*; -public class EquitySecurityServiceTest extends AbstractServiceTest{ +public class EquitySecurityServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher EQUITY_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); private final long ID = currentId.getAndIncrement(); private final int PARTITION = 0; @Autowired private EquitySecurityService equitySecurityService; + @PostConstruct protected void init() { super.init(); } /** - * {@link MoneyMarketSecurityService#newMoneyMarket(BaseRequest)}
- * Тест проверяет генерацию сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link MoneyMarketSecurityNewRequest}:
- * {@link MoneyMarketSecurityNewRequest#lotSize} - 1.0
- * {@link MoneyMarketSecurityNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
- * {@link MoneyMarketSecurityNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
- * {@link MoneyMarketSecurityNewRequest#nominalValue} - 1.0
- * {@link MoneyMarketSecurityNewRequest#nominalCurrency} - 1L
- * {@link MoneyMarketSecurityNewRequest#instrumentType} - "sdgaga"
- * {@link MoneyMarketSecurityNewRequest#fullName} - "estat"
+ * {@link EquitySecurityService#newEquity(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link EquitySecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link EquitySecurityNewRequest}:
*/ @Test - public void testNewEquity(){ + public void testNewEquity() { clearAllInImdg(equitySecurityImdg); final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_NEW; @@ -76,14 +66,9 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ } /** - * {@link MoneyMarketSecurityService#updateMoneyMarket(BaseRequest)} - * Тест проверяет обновление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link MoneyMarketSecurityUpdateRequest}:
- * {@link MoneyMarketSecurityUpdateRequest#fullName} - sfgsdfg
- * {@link MoneyMarketSecurityUpdateRequest#instrumentType} - qwerqwe
- * {@link MoneyMarketSecurityUpdateRequest#nominalCurrency} - RUB
- * {@link MoneyMarketSecurityUpdateRequest#nominalValue} - 2.0
- * {@link MoneyMarketSecurityUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)
+ * {@link EquitySecurityService#updateEquity(BaseRequest)} + * Тест проверяет обновление сущности {@link EquitySecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link EquitySecurityUpdateRequest}:
*/ @Test public void testUpdateEquity() { @@ -121,13 +106,13 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ } /** - * {@link MoneyMarketSecurityService#deleteMoneyMarket(BaseRequest)}
- * Тест проверяет удаление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * {@link EquitySecurityService#deleteEquity(BaseRequest)}
+ * Тест проверяет удаление сущности {@link EquitySecurity} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@link CommonDeleteRequest}:
* {@link CommonDeleteRequest#id} - Идентификатор записи
*/ @Test - public void testDeleteEquity(){ + public void testDeleteEquity() { clearAllInImdg(equitySecurityImdg); final String TOPIC = Consts.DESTINATION_EQUITY_SECURITY_DELETE; @@ -137,7 +122,8 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ Listing listingPrediction = new Listing(); listingPrediction = listingBuilder.byUpdateEquity(equityPrediction, listingPrediction); - listingImdg.insert(listingPrediction);listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + listingImdg.insert(listingPrediction); + listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); commonDeleteRequest.setId(ID); @@ -161,7 +147,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ LISTING_MATCHER.assertMatch(listingResult, listingPrediction); } - private EquitySecurity getEquitySecurity(){ + private EquitySecurity getEquitySecurity() { EquitySecurity equitySecurity = new EquitySecurity(); equitySecurity.setId(ID); equitySecurity.setSecuritySymbol("SecuritySymbol"); @@ -178,7 +164,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ return equitySecurity; } - private EquitySecurityNewRequest getEquitySecurityNewRequest(EquitySecurity equitySecurity){ + private EquitySecurityNewRequest getEquitySecurityNewRequest(EquitySecurity equitySecurity) { EquitySecurityNewRequest equitySecurityNewRequest = new EquitySecurityNewRequest(); equitySecurityNewRequest.setSecuritySymbol(equitySecurity.getSecuritySymbol()); equitySecurityNewRequest.setShortName(equitySecurity.getShortName()); @@ -194,7 +180,7 @@ public class EquitySecurityServiceTest extends AbstractServiceTest{ return equitySecurityNewRequest; } - private EquitySecurityUpdateRequest getEquitySecurityUpdateRequest(EquitySecurity equitySecurity){ + private EquitySecurityUpdateRequest getEquitySecurityUpdateRequest(EquitySecurity equitySecurity) { EquitySecurityUpdateRequest equitySecurityUpdateRequest = new EquitySecurityUpdateRequest(); equitySecurityUpdateRequest.setId(equitySecurity.getId()); equitySecurityUpdateRequest.setSecuritySymbol(equitySecurity.getSecuritySymbol()); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java index 1c4fe140b..818633338 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java @@ -5,16 +5,12 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Listing; -import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest; import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; -import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; import ru.spcex.clearing.securities.utils.MatcherFactory; import javax.annotation.PostConstruct; @@ -25,31 +21,25 @@ import java.util.Map; import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.securities.utils.TestUtils.*; -public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ +public class FixedIncomeSecurityServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher FIXED_INCOME_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); private final long ID = currentId.getAndIncrement(); private final int PARTITION = 0; @Autowired private FixedIncomeSecurityService fixedIncomeSecurityService; + @PostConstruct protected void init() { super.init(); } /** - * {@link MoneyMarketSecurityService#newMoneyMarket(BaseRequest)}
- * Тест проверяет генерацию сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link MoneyMarketSecurityNewRequest}:
- * {@link MoneyMarketSecurityNewRequest#lotSize} - 1.0
- * {@link MoneyMarketSecurityNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
- * {@link MoneyMarketSecurityNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.
- * {@link MoneyMarketSecurityNewRequest#nominalValue} - 1.0
- * {@link MoneyMarketSecurityNewRequest#nominalCurrency} - 1L
- * {@link MoneyMarketSecurityNewRequest#instrumentType} - "sdgaga"
- * {@link MoneyMarketSecurityNewRequest#fullName} - "estat"
+ * {@link FixedIncomeSecurityService#newFixedIncome(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link FixedIncomeSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link FixedIncomeSecurityNewRequest}:
*/ @Test - public void newFixedIncome(){ + public void newFixedIncome() { clearAllInImdg(fixedIncomeSecurityImdg); final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_NEW; @@ -77,14 +67,9 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ } /** - * {@link MoneyMarketSecurityService#updateMoneyMarket(BaseRequest)} - * Тест проверяет обновление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link MoneyMarketSecurityUpdateRequest}:
- * {@link MoneyMarketSecurityUpdateRequest#fullName} - sfgsdfg
- * {@link MoneyMarketSecurityUpdateRequest#instrumentType} - qwerqwe
- * {@link MoneyMarketSecurityUpdateRequest#nominalCurrency} - RUB
- * {@link MoneyMarketSecurityUpdateRequest#nominalValue} - 2.0
- * {@link MoneyMarketSecurityUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)
+ * {@link FixedIncomeSecurityService#updateFixedIncome(BaseRequest)} + * Тест проверяет обновление сущности {@link FixedIncomeSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link FixedIncomeSecurityUpdateRequest}:
*/ @Test public void updateFixedIncome() { @@ -123,13 +108,13 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ } /** - * {@link MoneyMarketSecurityService#deleteMoneyMarket(BaseRequest)}
- * Тест проверяет удаление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.
+ * {@link FixedIncomeSecurityService#deleteFixedIncome(BaseRequest)}
+ * Тест проверяет удаление сущности {@link FixedIncomeSecurity} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@link CommonDeleteRequest}:
* {@link CommonDeleteRequest#id} - Идентификатор записи
*/ @Test - public void deleteFixedIncome(){ + public void deleteFixedIncome() { clearAllInImdg(moneyMarketSecurityMap); final String TOPIC = Consts.DESTINATION_FIXED_INCOME_SECURITY_DELETE; @@ -139,7 +124,8 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ Listing listingPrediction = new Listing(); listingPrediction = listingBuilder.byFixedIncomeEquity(fixedIncomePrediction, listingPrediction); - listingImdg.insert(listingPrediction);listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + listingImdg.insert(listingPrediction); + listingPrediction.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); commonDeleteRequest.setId(ID); @@ -163,7 +149,7 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ LISTING_MATCHER.assertMatch(listingResult, listingPrediction); } - private FixedIncomeSecurity getFixedIncomeSecurity(){ + private FixedIncomeSecurity getFixedIncomeSecurity() { FixedIncomeSecurity fixedIncome = new FixedIncomeSecurity(); fixedIncome.setId(ID); fixedIncome.setSecuritySymbol("SecuritySymbol"); @@ -187,7 +173,7 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ return fixedIncome; } - private FixedIncomeSecurityNewRequest getFixedIncomeSecurityNewRequest(FixedIncomeSecurity fixedIncomeSecurity){ + private FixedIncomeSecurityNewRequest getFixedIncomeSecurityNewRequest(FixedIncomeSecurity fixedIncomeSecurity) { FixedIncomeSecurityNewRequest fixedIncomeSecurityNewRequest = new FixedIncomeSecurityNewRequest(); fixedIncomeSecurityNewRequest.setSecuritySymbol(fixedIncomeSecurity.getSecuritySymbol()); fixedIncomeSecurityNewRequest.setShortName(fixedIncomeSecurity.getShortName()); @@ -208,7 +194,7 @@ public class FixedIncomeSecurityServiceTest extends AbstractServiceTest{ return fixedIncomeSecurityNewRequest; } - private FixedIncomeSecurityUpdateRequest getFixedIncomeSecurityUpdateRequest(FixedIncomeSecurity fixedIncomeSecurity){ + private FixedIncomeSecurityUpdateRequest getFixedIncomeSecurityUpdateRequest(FixedIncomeSecurity fixedIncomeSecurity) { FixedIncomeSecurityUpdateRequest equitySecurityUpdateRequest = new FixedIncomeSecurityUpdateRequest(); equitySecurityUpdateRequest.setId(fixedIncomeSecurity.getId()); equitySecurityUpdateRequest.setSecuritySymbol(fixedIncomeSecurity.getSecuritySymbol()); diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyNewRequest.java new file mode 100644 index 000000000..f335bf79c --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyNewRequest.java @@ -0,0 +1,26 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CurrencyNewRequest{ + @JsonProperty + public String countryCode; + @JsonProperty + public String currencyCode; + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public void setCurrencyCode(String currencyCode) { + this.currencyCode = currencyCode; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyUpdateRequest.java new file mode 100644 index 000000000..94b911f33 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CurrencyUpdateRequest.java @@ -0,0 +1,39 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import ru.spcex.platform.classes.base.interfaces.WithId; + +public class CurrencyUpdateRequest implements WithId { + @JsonProperty + public Long id; + @JsonProperty + public String countryCode; + @JsonProperty + public String currencyCode; + + + @Override + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public void setCurrencyCode(String currencyCode) { + this.currencyCode = currencyCode; + } +} From edff45ebaeecfdb5cf52c48f3d221dd7cff784d5 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Wed, 5 Apr 2023 19:56:57 +0300 Subject: [PATCH 50/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20CouponPeriodSer?= =?UTF-8?q?vice=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BA=20=D0=BD?= =?UTF-8?q?=D0=B5=D0=BC=D1=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../securities/errors/SecuritiesError.java | 2 + .../service/cud/CouponPeriodService.java | 89 ++++++++++++++++ .../service/cud/CurrencyService.java | 8 +- .../validation/ValidationProvider.java | 24 +++++ .../rule/CouponPeriodNewValidationRule.java | 48 +++++++++ .../CouponPeriodUpdateValidationRule.java | 48 +++++++++ .../service/AbstractServiceTest.java | 11 +- .../service/CouponPeriodServiceTest.java | 100 ++++++++++++++++++ .../service/CurrencyServiceTest.java | 6 +- .../platform/messaging/domain/Consts.java | 7 +- .../securitites/CouponPeriodNewRequest.java | 46 ++++++++ .../CouponPeriodUpdateRequest.java | 59 +++++++++++ 12 files changed, 431 insertions(+), 17 deletions(-) create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodUpdateValidationRule.java create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java index 7bffa0a3f..5a64dc08e 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java @@ -8,6 +8,8 @@ public enum SecuritiesError implements IErrorEnumId { InstrumentAlreadyExists(1010L), InstrumentNotFound(1011L), InstrumentNotActive(1012L), + CouponPeriodAlreadyExists(1013L), + CouponPeriodNotFound(1014L), CurrencyAlreadyExists(1015L), CurrencyNotFound(1016L), diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java new file mode 100644 index 000000000..96e55f284 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java @@ -0,0 +1,89 @@ +package ru.spcex.clearing.securities.service.cud; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.instrument.issue.CouponPeriod; +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.securitites.CouponPeriodNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; + +@Service +public class CouponPeriodService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg couponPeriodImdg; + private final ImdgProvider imdgProvider; + private final ImdgId idGenerator; + private final ValidationProvider validation; + private final ValidationHelper validationHelper; + + @Autowired + public CouponPeriodService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationProvider validation, + ValidationHelper validationHelper) { + super(kafkaQueue, kafkaProducer); + this.validation = validation; + this.couponPeriodImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CouponPeriod, CouponPeriod.class); + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.validationHelper = validationHelper; + } + + @Override + public void afterPropertiesSet() { + callback(CouponPeriodNewRequest.class) + .setFunction(this::newCouponPeriod) + .forDestination(Consts.DESTINATION_COUPON_PERIOD_NEW, callbacks::put); + callback(CouponPeriodUpdateRequest.class) + .setFunction(this::updateCouponPeriod) + .forDestination(Consts.DESTINATION_COUPON_PERIOD_UPDATE, callbacks::put); + imdgProvider.waitAvailable(); + init(); + } + + private RequestInfoUpdate newCouponPeriod(BaseRequest userRequest) { + CouponPeriodNewRequest req = userRequest.getRequestPayload(); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.couponPeriodNewValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + log.debug("newCurrency received"); + CouponPeriod couponPeriod = new CouponPeriod(); + couponPeriod.setId(idGenerator.nextId()); + couponPeriod.setSecurityId(req.getSecurityId()); + couponPeriod.setPeriodEndDate(req.getPeriodEndDate()); + couponPeriod.setPeriodStartDate(req.getPeriodStartDate()); + couponPeriodImdg.insert(couponPeriod); + log.debug("successfully processed, request id {}, new object id {}", userRequest.getId(), couponPeriod.getId()); + return null; // default success + } + + private RequestInfoUpdate updateCouponPeriod(BaseRequest userRequest) { + CouponPeriodUpdateRequest req = userRequest.getRequestPayload(); + log.debug("updateCurrency received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.couponPeriodUpdateValidator()); + if (requestInfoUpdate != null) return requestInfoUpdate; + + CouponPeriod couponPeriod = couponPeriodImdg.getSingleObjectBySQL(String.format("securityId = %s", req.getSecurityId())); + couponPeriod.setPeriodEndDate(req.getPeriodEndDate()); + couponPeriod.setPeriodStartDate(req.getPeriodStartDate()); + couponPeriodImdg.update(couponPeriod); + return null; + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java index 52e01c60f..8796e8e76 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java @@ -15,13 +15,11 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyNewRe import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; -import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.validation.ValidationProvider; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; -import ru.spcex.platform.imdg.api.ImdgTransaction; @Service public class CurrencyService extends QueueConsumer implements InitializingBean { @@ -31,7 +29,6 @@ public class CurrencyService extends QueueConsumer implements InitializingBean { private final ImdgId idGenerator; private final ValidationProvider validation; private final ValidationHelper validationHelper; - private final ListingBuilder listingBuilder = new ListingBuilder(); @Autowired public CurrencyService(Consumer kafkaQueue, @@ -51,16 +48,15 @@ public class CurrencyService extends QueueConsumer implements InitializingBean { public void afterPropertiesSet() { callback(CurrencyNewRequest.class) .setFunction(this::newCurrency) - .forDestination(Consts.DESTINATION_СURRENCY_NEW, callbacks::put); + .forDestination(Consts.DESTINATION_CURRENCY_NEW, callbacks::put); callback(CurrencyUpdateRequest.class) .setFunction(this::updateCurrency) - .forDestination(Consts.DESTINATION_СURRENCY_UPDATE, callbacks::put); + .forDestination(Consts.DESTINATION_CURRENCY_UPDATE, callbacks::put); imdgProvider.waitAvailable(); init(); } private RequestInfoUpdate newCurrency(BaseRequest userRequest) { - ImdgTransaction transaction = imdgProvider.newTransaction(); CurrencyNewRequest req = userRequest.getRequestPayload(); RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.currencyNewValidator()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index ed7c2f5a5..a8a055fd3 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -29,6 +29,7 @@ public class ValidationProvider { private final Imdg bondTypeDictionaryImdg; private final Imdg companyImdg; private final Imdg currencyImdg; + private final Imdg couponPeriodImdg; public ValidationProvider(ImdgProvider imdgProvider) { @@ -43,6 +44,7 @@ public class ValidationProvider { this.bondTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BondTypeDictionary, SpcexObjectBase.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, SpcexObjectBase.class); this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, SpcexObjectBase.class); + this.couponPeriodImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CouponPeriod, SpcexObjectBase.class); } public Function mmsNewValidator() { @@ -241,4 +243,26 @@ public class ValidationProvider { ); }; } + + public Function couponPeriodNewValidator() { + return currencyRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(currencyRequest); + context.addImdg(IMDGDistributedNames.Map_CouponPeriod, couponPeriodImdg); + return new ValidatorImpl<>(context, + CouponPeriodNewValidationRule.CouponPeriodNotExists + ); + }; + } + + public Function couponPeriodUpdateValidator() { + return currencyRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(currencyRequest); + context.addImdg(IMDGDistributedNames.Map_CouponPeriod, couponPeriodImdg); + return new ValidatorImpl<>(context, + CouponPeriodUpdateValidationRule.CouponPeriodExists + ); + }; + } } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java new file mode 100644 index 000000000..7a95f7298 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java @@ -0,0 +1,48 @@ +package ru.spcex.clearing.securities.validation.rule; + +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodNewRequest; +import ru.spcex.clearing.securities.errors.SecuritiesError; +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.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Map; +import java.util.Optional; + +public enum CouponPeriodNewValidationRule implements IValidationRule> { + CouponPeriodNotExists() { + @Override + public Optional validate(ImdgValidationContext context) { + CouponPeriodNewRequest action = context.getValidatedObject(); + if (action.getSecurityId() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "securityId"); + } + Imdg imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_CouponPeriod, SpcexObjectBase.class); + SpcexObjectBase couponPeriod = imdgDictionary.getSingleObjectByFieldValues(Map.of( + "securityId", action.getSecurityId())); + if (couponPeriod != null) { + return of(SecuritiesError.CouponPeriodAlreadyExists, "securityId"); + } + if (action.getPeriodEndDate() == null && action.getPeriodStartDate() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "periodEndDate", "periodStartDate"); + } + if (action.getPeriodEndDate() == null || action.getPeriodStartDate() == null) { + if (action.getPeriodStartDate() == null) + return of(SecuritiesError.RequiredFieldIsEmpty, "periodStartDate"); + return of(SecuritiesError.RequiredFieldIsEmpty, "periodEndDate"); + } + if (action.getPeriodEndDate().isBefore(action.getPeriodStartDate())) { + return of(SecuritiesError.WrongFieldValue, "periodEndDate", "periodStartDate"); + } + return empty(); + } + }; + + @Override + public String ruleName() { + return "MmsNewValidationRule." + name(); + } +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodUpdateValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodUpdateValidationRule.java new file mode 100644 index 000000000..9aeb7ffc1 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodUpdateValidationRule.java @@ -0,0 +1,48 @@ +package ru.spcex.clearing.securities.validation.rule; + +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodUpdateRequest; +import ru.spcex.clearing.securities.errors.SecuritiesError; +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.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Map; +import java.util.Optional; + +public enum CouponPeriodUpdateValidationRule implements IValidationRule> { + CouponPeriodExists() { + @Override + public Optional validate(ImdgValidationContext context) { + CouponPeriodUpdateRequest action = context.getValidatedObject(); + if (action.getSecurityId() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "securityId"); + } + Imdg imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_CouponPeriod, SpcexObjectBase.class); + SpcexObjectBase currency = imdgDictionary.getSingleObjectByFieldValues(Map.of( + "securityId", action.getSecurityId())); + if (currency == null) { + return of(SecuritiesError.CouponPeriodNotFound, "securityId"); + } + if (action.getPeriodEndDate() == null && action.getPeriodStartDate() == null) { + return of(SecuritiesError.RequiredFieldIsEmpty, "periodEndDate", "periodStartDate"); + } + if (action.getPeriodEndDate() == null || action.getPeriodStartDate() == null) { + if (action.getPeriodStartDate() == null) + return of(SecuritiesError.RequiredFieldIsEmpty, "periodStartDate"); + return of(SecuritiesError.RequiredFieldIsEmpty, "periodEndDate"); + } + if (action.getPeriodEndDate().isBefore(action.getPeriodStartDate())) { + return of(SecuritiesError.WrongFieldValue, "periodEndDate", "periodStartDate"); + } + return empty(); + } + }; + + @Override + public String ruleName() { + return "MmsNewValidationRule." + name(); + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java index 4d9943720..e83f7f6cd 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -11,6 +11,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; 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.instrument.issue.CouponPeriod; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Currency; @@ -23,10 +24,7 @@ import ru.spcex.clearing.securities.config.ErrorResolverConfig; import ru.spcex.clearing.securities.config.ImdgTestConfig; import ru.spcex.clearing.securities.config.KafkaTestConfig; import ru.spcex.clearing.securities.config.ValidationConfig; -import ru.spcex.clearing.securities.service.cud.CurrencyService; -import ru.spcex.clearing.securities.service.cud.EquitySecurityService; -import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; -import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; +import ru.spcex.clearing.securities.service.cud.*; import ru.spcex.clearing.securities.utils.MatcherFactory; import ru.spcex.clearing.securities.utils.TestUtils; import ru.spcex.clearing.securities.validation.ValidationProvider; @@ -41,10 +39,11 @@ import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFie @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { + CouponPeriodService.class, + CurrencyService.class, EquitySecurityService.class, FixedIncomeSecurityService.class, MoneyMarketSecurityService.class, - CurrencyService.class, ImdgTestConfig.class, KafkaTestConfig.class, ValidationProvider.class, @@ -65,6 +64,7 @@ public abstract class AbstractServiceTest { protected Imdg bondTypeDictionaryImdg; protected Imdg companyImdg; protected Imdg currencyImdg; + protected Imdg couponPeriodImdg; public static String RATE = "RATE"; protected String EQTY = "EQTY"; @@ -97,6 +97,7 @@ public abstract class AbstractServiceTest { this.bondTypeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_BondTypeDictionary, BondTypeDictionary.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class); + this.couponPeriodImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CouponPeriod, CouponPeriod.class); InstrumentTypeDictionary instrumentTypeDictionary = new InstrumentTypeDictionary(); instrumentTypeDictionary.setId(1L); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java new file mode 100644 index 000000000..295d403b0 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java @@ -0,0 +1,100 @@ +package ru.spcex.clearing.securities.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import ru.clearing.classes.statics.data.instrument.issue.CouponPeriod; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodUpdateRequest; +import ru.spcex.clearing.securities.service.cud.CouponPeriodService; +import ru.spcex.clearing.securities.utils.MatcherFactory; + +import javax.annotation.PostConstruct; +import java.time.LocalDate; + +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.securities.utils.TestUtils.*; + +public class CouponPeriodServiceTest extends AbstractServiceTest { + private static final MatcherFactory.Matcher COUPON_PERIOD_MATCHER = usingIgnoringFieldsComparator(); + private final long ID = currentId.getAndIncrement(); + private final long securityId = 3123L; + private final int PARTITION = 0; + private final String countryCode = "countryCode"; + private final String currencyCode = "currencyCode"; + @Autowired + private CouponPeriodService couponPeriodService; + + @PostConstruct + protected void init() { + super.init(); + } + + /** + * {@link CouponPeriodService#newCouponPeriod(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link CouponPeriod} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CouponPeriodNewRequest}:
+ */ + @Test + public void testNewCurrency() { + clearAllInImdg(couponPeriodImdg); + final String TOPIC = Consts.DESTINATION_COUPON_PERIOD_NEW; + + final CouponPeriod currencyPrediction = new CouponPeriod(); + currencyPrediction.setSecurityId(securityId); + currencyPrediction.setPeriodEndDate(LocalDate.now()); + currencyPrediction.setPeriodStartDate(LocalDate.ofEpochDay(0)); + final CouponPeriodNewRequest request = new CouponPeriodNewRequest(); + request.setSecurityId(securityId); + request.setPeriodEndDate(LocalDate.now()); + request.setPeriodStartDate(LocalDate.ofEpochDay(0)); + + + //ACT + String jsonString = getJsonStringForNew(request, ID); + + addRecordToKafka((MockConsumer) couponPeriodService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + CouponPeriod result = couponPeriodImdg.getSingleObjectBySQL(String.format("securityId = %s", currencyPrediction.getSecurityId())); + currencyPrediction.setId(result.getId()); + COUPON_PERIOD_MATCHER.assertMatch(result, currencyPrediction); + } + + /** + * {@link CouponPeriodService#updateCouponPeriod(BaseRequest)} + * Тест проверяет обновление сущности {@link CouponPeriod} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CouponPeriodUpdateRequest}:
+ */ + @Test + public void testUpdateCurrency() { + clearAllInImdg(couponPeriodImdg); + final String TOPIC = Consts.DESTINATION_COUPON_PERIOD_UPDATE; + final CouponPeriod currencyPrediction = new CouponPeriod(); + currencyPrediction.setSecurityId(securityId); + currencyPrediction.setPeriodEndDate(LocalDate.ofEpochDay(0)); + currencyPrediction.setPeriodStartDate(LocalDate.ofEpochDay(0)); + couponPeriodImdg.insert(currencyPrediction); + final CouponPeriodNewRequest request = new CouponPeriodNewRequest(); + currencyPrediction.setPeriodEndDate(LocalDate.now()); + request.setSecurityId(securityId); + request.setPeriodEndDate(LocalDate.now()); + request.setPeriodStartDate(LocalDate.ofEpochDay(0)); + + //ACT + String jsonString = getJsonStringForUPDATE(request, ID); + + addRecordToKafka((MockConsumer) couponPeriodService.getConsumer(), TOPIC, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + CouponPeriod result = couponPeriodImdg.getSingleObjectBySQL(String.format("securityId = %s", currencyPrediction.getSecurityId())); + currencyPrediction.setId(result.getId()); + COUPON_PERIOD_MATCHER.assertMatch(result, currencyPrediction); + } +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java index b52eeac72..525074512 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java @@ -17,7 +17,7 @@ import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFie import static ru.spcex.clearing.securities.utils.TestUtils.*; public class CurrencyServiceTest extends AbstractServiceTest { - private static final MatcherFactory.Matcher CURRENCY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + private static final MatcherFactory.Matcher CURRENCY_MATCHER = usingIgnoringFieldsComparator(); private final long ID = currentId.getAndIncrement(); private final int PARTITION = 0; private final String countryCode = "countryCode"; @@ -38,7 +38,7 @@ public class CurrencyServiceTest extends AbstractServiceTest { @Test public void testNewCurrency() { clearAllInImdg(currencyImdg); - final String TOPIC = Consts.DESTINATION_СURRENCY_NEW; + final String TOPIC = Consts.DESTINATION_CURRENCY_NEW; final Currency currencyPrediction = new Currency(); currencyPrediction.setCountryCode(countryCode); @@ -68,7 +68,7 @@ public class CurrencyServiceTest extends AbstractServiceTest { @Test public void testUpdateCurrency() { clearAllInImdg(currencyImdg); - final String TOPIC = Consts.DESTINATION_СURRENCY_UPDATE; + final String TOPIC = Consts.DESTINATION_CURRENCY_UPDATE; final Currency currencyPrediction = new Currency(); currencyPrediction.setId(ID); currencyPrediction.setCountryCode("ExistsCountryCode"); 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 b4392e713..69bfd494d 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 @@ -13,9 +13,10 @@ public interface Consts { String DESTINATION_FIXED_INCOME_SECURITY_UPDATE = "fixed-income-security-update"; String DESTINATION_FIXED_INCOME_SECURITY_DELETE = "fixed-income-security-delete"; - String DESTINATION_СURRENCY_NEW = "currency-new"; - String DESTINATION_СURRENCY_UPDATE = "currency-update"; - String DESTINATION_СURRENCY_DELETE = "currency-delete"; + String DESTINATION_CURRENCY_NEW = "currency-new"; + String DESTINATION_CURRENCY_UPDATE = "currency-update"; + String DESTINATION_COUPON_PERIOD_NEW = "coupon_period-new"; + String DESTINATION_COUPON_PERIOD_UPDATE = "coupon_period-update"; String DESTINATION_KEY_RATE_NEW = "key-rate-new"; String DESTINATION_KEY_RATE_UPDATE = "key-rate-update"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java new file mode 100644 index 000000000..23118e3cb --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; + +import java.time.LocalDate; + +public class CouponPeriodNewRequest { + @JsonProperty + public Long securityId; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate periodEndDate; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate periodStartDate; + + public Long getSecurityId() { + return securityId; + } + + public void setSecurityId(Long securityId) { + this.securityId = securityId; + } + + public LocalDate getPeriodEndDate() { + return periodEndDate; + } + + public void setPeriodEndDate(LocalDate periodEndDate) { + this.periodEndDate = periodEndDate; + } + + public LocalDate getPeriodStartDate() { + return periodStartDate; + } + + public void setPeriodStartDate(LocalDate periodStartDate) { + this.periodStartDate = periodStartDate; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java new file mode 100644 index 000000000..96a344661 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java @@ -0,0 +1,59 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.securitites; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; +import ru.spcex.platform.classes.base.interfaces.WithId; + +import java.time.LocalDate; + +public class CouponPeriodUpdateRequest implements WithId { + @JsonProperty + public Long id; + @JsonProperty + public Long securityId; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate periodEndDate; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate periodStartDate; + + + @Override + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getSecurityId() { + return securityId; + } + + public void setSecurityId(Long securityId) { + this.securityId = securityId; + } + + public LocalDate getPeriodEndDate() { + return periodEndDate; + } + + public void setPeriodEndDate(LocalDate periodEndDate) { + this.periodEndDate = periodEndDate; + } + + public LocalDate getPeriodStartDate() { + return periodStartDate; + } + + public void setPeriodStartDate(LocalDate periodStartDate) { + this.periodStartDate = periodStartDate; + } +} From 1adc5db487b9c770264fd28baa7d5e972fe99669 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 20:58:17 +0300 Subject: [PATCH 51/90] company-service: refactoring CompanyService + transaction --- .../clearing/company/error/CompanyErrors.java | 2 +- .../service/AccountNotificationHelper.java | 64 +++++ .../company/service/CompanyService.java | 252 ++++++++---------- .../company/service/CompanySymbolService.java | 11 +- .../company/service/RelationHelper.java | 94 +++++++ .../sdf01/AccountTerminationRequest.java | 36 +++ 6 files changed, 314 insertions(+), 145 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountTerminationRequest.java 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 84cba81e5..02ad9886e 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 @@ -19,7 +19,7 @@ public enum CompanyErrors implements IErrorEnumId { ContactNotFound(3015L), // Контакт компании %s не найден. CategoryNotFound(3016L), // Категория компании %s не найдена. CategoryAlreadySet(3017L), // Компании %s уже присвоена категория %s. - CompanyAlreadyHas_(3018L), // У компании %s присутствуют обязательства. + CompanyAlreadyHasLiabilities(3018L), // У компании %s присутствуют обязательства. EditCompanySymbols(3020L), // Тип реквизита компании %s не может быть изменен. EditContactType(3021L) // Тип контакта компании %s не может быть изменен. ; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java new file mode 100644 index 000000000..cfd70c1c3 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java @@ -0,0 +1,64 @@ +package ru.spcex.clearing.company.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets; +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.account.sdf01.AccountTerminationRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.math.BigDecimal; +import java.util.Collection; + +@Service +public class AccountNotificationHelper { + private final Logger log = LoggerFactory.getLogger(getClass()); + + KafkaSender kafkaSender; + Imdg liabilitiesClaimsAssetsMap; + Imdg accountMap; + + @Autowired + public AccountNotificationHelper( + KafkaSender kafkaSender, + ImdgProvider imdgProvider) { + this.kafkaSender = kafkaSender; + this.liabilitiesClaimsAssetsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsAssets, LiabilitiesClaimsAssets.class); + this.accountMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + + } + + public CompanyErrors accountTerminationNotification(Long companyId) { + Collection accounts = accountMap.getCollectionObjectsBySQL("companyId=" + companyId); + log.trace("Found {} accounts by company {}", accounts.size(), companyId); + for (Account account : accounts) { + Collection liabilities = liabilitiesClaimsAssetsMap.getCollectionObjectsBySQL("accountId=" + account.getId()); + for (LiabilitiesClaimsAssets liability : liabilities) { + if (liability.getLiabilitiesQuantity() != null && BigDecimal.ZERO.compareTo(liability.getLiabilitiesQuantity()) == 0) { + return CompanyErrors.CompanyAlreadyHasLiabilities; + } + } + } + log.debug("Sending messages to account-service for {} account", accounts.size()); + for (Account account : accounts) { + Long reqId = kafkaSender.sendRequestToQueue(Consts.ACCOUNT_TERMINATION, createAccountsRequest(companyId, account)); + log.debug("For account[{}] sended termination request id={}", account.getId(), reqId); + } + return null; + } + + private AccountTerminationRequest createAccountsRequest(Long companyId, Account account) { + AccountTerminationRequest r = new AccountTerminationRequest(); + r.setCompanyId(companyId); + r.setAccount(account.getAccount()); + r.setAccountId(account.getId()); + return r; + } +} \ No newline at end of file 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 c155a2b55..ed1127656 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 @@ -26,6 +26,7 @@ import ru.spcex.platform.enumeration.*; 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.IMessageResolver; import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; @@ -36,15 +37,16 @@ import java.util.Map; import java.util.Objects; import java.util.function.Function; +// todo добавить транзакции! Это важно из-за AccountNotification @Service public class CompanyService extends QueueConsumer implements InitializingBean { - protected static final Long SPVB_ID = 1L; // СПВБ private final Logger log = LoggerFactory.getLogger(getClass()); private final RequestHelper requestHelper; - private final Imdg companyMap; + private final ImdgProvider imdgProvider; + // private final Imdg companyMap; private final Imdg companySymnbolsMap; - private final Imdg relationMap; + // private final Imdg relationMap; private final ImdgId idSequence; protected UserRoleVerification userRoleVerification; protected IMessageResolver messageResolver; @@ -55,6 +57,8 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private Function companyDeleteRequestValidator; protected CompanySymbolService companySymbolService; + protected AccountNotificationHelper accountNotification; + protected RelationHelper relationHelper; @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, @@ -69,13 +73,18 @@ public class CompanyService extends QueueConsumer implements InitializingBean { @Qualifier("CompanyDeleteRequestValidator") Function companyDeleteRequestValidator, - CompanySymbolService companySymbolService + CompanySymbolService companySymbolService, + AccountNotificationHelper accountNotification, + RelationHelper relationHelper ) { super(kafkaQueue, kafkaProducer); + this.imdgProvider = imdgProvider; this.messageResolver = messageResolver; this.requestHelper = new RequestHelper(log, messageResolver); - this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); - this.relationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); +// this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); +// this.relationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + + this.companySymnbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); this.userRoleVerification = userRoleVerification; @@ -84,6 +93,8 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companyUpdateRequestValidator = companyUpdateRequestValidator; this.companyDeleteRequestValidator = companyDeleteRequestValidator; this.companySymbolService = companySymbolService; + this.accountNotification = accountNotification; + this.relationHelper = relationHelper; } @Override @@ -128,19 +139,31 @@ public class CompanyService extends QueueConsumer implements InitializingBean { company.setShortName(req.getShortName()); company.setFullName(req.getFullName()); - if (req.getCompanySymbol() != null) { - CompanySymbols newSymbol = companySymbolService.createCompanySymbol(company.getId(), req.getCompanySymbol(), req.getCompanySymbolValue()); - updateCompanyBySymbol(company, newSymbol); - } + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + if (req.getCompanySymbol() != null) { + CompanySymbols newSymbol = companySymbolService.createCompanySymbol(transaction, company.getId(), req.getCompanySymbol(), req.getCompanySymbolValue()); + updateCompanyBySymbol(company, newSymbol); + } - company.setWorkflowStatus(req.getWorkflowStatus()); + company.setWorkflowStatus(req.getWorkflowStatus()); - companyMap.insert(company); - log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", - companyNewRequestBaseRequest.getId(), company.getId()); - createNewRelation(company); - if (!(WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))) { // Block - onChangeWorkflowStatus(company, null, company.getWorkflowStatus()); + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + companyMap.insert(company); + log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", + companyNewRequestBaseRequest.getId(), company.getId()); + relationHelper.createNewRelation(transaction, company); + if (!(WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))) { // Block + relationHelper.onChangeWorkflowStatus(transaction, company, null, company.getWorkflowStatus()); + } + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); } return null; } @@ -153,36 +176,49 @@ public class CompanyService extends QueueConsumer implements InitializingBean { RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyUpdateRequestBaseRequest, companyUpdateRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } - Company company = companyMap.getSingleObjectByID(updateRequest.getId()); // todo use validationContext. - if (company == null) { - 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()); - } + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); - company.setUpdated(Instant.now()); - company.setShortName(updateRequest.getShortName()); - company.setFullName(updateRequest.getFullName()); + Company company = companyMap.getSingleObjectByID(updateRequest.getId()); + if (company == null) { + 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 (updateRequest.getCompanySymbol() != null || updateRequest.getCompanySymbolValue() != null) { - log.trace("Request field CompanySymbol, CompanySymbolValue ignore for update company request."); - } + company.setUpdated(Instant.now()); + company.setShortName(updateRequest.getShortName()); + company.setFullName(updateRequest.getFullName()); + + if (updateRequest.getCompanySymbol() != null || updateRequest.getCompanySymbolValue() != null) { + log.trace("Request field CompanySymbol, CompanySymbolValue ignore for update company request."); + } // CompanySymbols не обновляем - String prevStatus = company.getWorkflowStatus(); - if (updateRequest.getWorkflowStatus() != null) { - company.setWorkflowStatus(updateRequest.getWorkflowStatus()); - if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { - onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); + String prevStatus = company.getWorkflowStatus(); + if (updateRequest.getWorkflowStatus() != null) { + company.setWorkflowStatus(updateRequest.getWorkflowStatus()); + if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { + relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + } else { + log.trace("Status was not changed"); + } } else { - log.trace("Status was not changed"); + log.trace("Null new WorkflowStatus"); } - } else { - log.trace("Null new WorkflowStatus"); + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); } return null; } @@ -206,65 +242,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { } } - protected void kafkaSentAccountNotification(Company aboutBlockCompany) { - log.debug("Send message to kafka..."); - //todo message to queue - } - - protected void createNewRelation(Company company) { - Relation relation = new Relation(); - relation.setId(idSequence.nextId()); - relation.setCreated(Instant.now()); - relation.setUpdated(relation.getCreated()); - - relation.setConsumerId(company.getId()); - relation.setSupplierId(SPVB_ID); // 1 СПВБ - relation.setServiceStatus(WorkflowStatus.Active.getKey()); - relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR - relation.setServiceProduct(ServiceProduct.ZERO.getKey()); - log.debug("New Relation[{}] created.", relation.getId()); - relationMap.insert(relation); - } - - /** - * @param company - * @param oldStatus - * @param newStatus WorkflowStatus.Active - при возобналвении; WorkflowStatus.Blocked - при блокировки/расторжении - */ - private void onChangeWorkflowStatus(Company company, String oldStatus, String newStatus) { - log.debug("Company id={} status changed from {} to {}", - company.getId(), oldStatus, company.getWorkflowStatus()); - assert Objects.equals(newStatus, company.getWorkflowStatus()); - String query = String.format("consumerId=%s", company.getId()); - Collection relations = relationMap.getCollectionObjectsBySQL(query); - log.trace("Selected {} Relation by query: {}", relations.size(), query); - Instant now = Instant.now(); - for (Relation relation : relations) { - boolean modified = false; - if (WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { - if (!ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus())) { - relation.setServiceStatus(ServiceStatus.Reopened.getKey()); - modified = true; - } - } else if (WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { - if (!ServiceStatus.Closed.equalsByKey(relation.getServiceStatus())) { - relation.setServiceStatus(ServiceStatus.Closed.getKey()); - modified = true; - } - } - if (modified) { - relation.setUpdated(now); - log.debug("Relation id={} updated", relation.getId()); - relationMap.update(relation); - } - } - - if (WorkflowStatus.Blocked.equalsByKey(newStatus)) { - kafkaSentAccountNotification(company); - } - } - - /** * Блокировка компании * @@ -279,54 +256,45 @@ public class CompanyService extends QueueConsumer implements InitializingBean { RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyBlockRequestBaseRequest, companyDeleteRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } - Company company = companyMap.getSingleObjectByID(request.getId()); - if (company == null) { - log.warn("Company {} not found", request.getId()); - return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyNotFound, request.getId()); + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyMap.getSingleObjectByID(request.getId()); + if (company == null) { + log.warn("Company {} not found", request.getId()); + return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyNotFound, request.getId()); + } + + company.setUpdated(Instant.now()); + + CompanySymbols companySymbol = companySymnbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); + if (companySymbol == null) { + log.warn("CompanySymbols not found for companyId={}", company.getId()); + } else { + log.trace("Found CompanySymbols.id={} for companyId={}", companySymbol.getId(), company.getId()); + updateCompanyBySymbol(company, companySymbol); + } + + String prevStatus = company.getWorkflowStatus(); + company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); + log.debug("Update company.id={}", company.getId()); + companyMap.update(company); + + relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); } - - company.setUpdated(Instant.now()); - - CompanySymbols companySymbol = companySymnbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); - if (companySymbol == null) { - log.warn("CompanySymbols not found for companyId={}", company.getId()); - } else { - log.trace("Found CompanySymbols.id={} for companyId={}", companySymbol.getId(), company.getId()); - updateCompanyBySymbol(company, companySymbol); - } - - String prevStatus = company.getWorkflowStatus(); - company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - log.debug("Update company.id={}", company.getId()); - companyMap.update(company); - - onChangeWorkflowStatus(company, prevStatus, company.getWorkflowStatus()); return null; // Company company = companyMap.getSingleObjectByID(req.getId()); // companyMap.delete(company); } - - /** - * IV - сообщения на добавления документа расторжения договора - * - * @param companyId - */ - public synchronized void onRastorjeniye(Long companyId) { - Company company = companyMap.getSingleObjectByID(companyId); - if (company == null) { - log.warn("Company {} not found", companyId); - return; - } - - if (!WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { - log.debug("Update company.id={}", company.getId()); - company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - company.setUpdated(Instant.now()); - companyMap.update(company); - } else { - log.trace("Company {} already has blocked.", companyId); - } - } } 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 f52d1b24a..080a82d3a 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 @@ -17,6 +17,7 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.ImdgTransaction; import java.util.Objects; @@ -53,7 +54,8 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB log.debug("successfully processed, id {}", companySymbols.getId()); } - public CompanySymbols createCompanySymbol(Long companyId, String companySymbol, String companySymbolValue) { + + public CompanySymbols createCompanySymbol(ImdgTransaction transaction, Long companyId, String companySymbol, String companySymbolValue) { Objects.requireNonNull(companyId); CompanySymbols newSymbol = new CompanySymbols(); newSymbol.setId(idSequence.nextId()); @@ -61,7 +63,12 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB newSymbol.setCompanySymbol(companySymbol); newSymbol.setCompanySymbolValue(companySymbolValue); log.debug("Created new companySymbols.id={} for company {}", newSymbol.getId(), companyId); - companySymbolsMap.insert(newSymbol); + if (transaction == null) { + companySymbolsMap.insert(newSymbol); + } else { + Imdg tMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + tMap.insert(newSymbol); + } return newSymbol; } } 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/RelationHelper.java new file mode 100644 index 000000000..61fb15e7c --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java @@ -0,0 +1,94 @@ +package ru.spcex.clearing.company.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +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.ImdgTransaction; +import ru.spcex.platform.utils.error.ValidationException; + +import java.time.Instant; +import java.util.Collection; +import java.util.Objects; + +@Service +public class RelationHelper { + protected static final Long SPVB_ID = 1L; // СПВБ + protected final Logger log = LoggerFactory.getLogger(getClass()); + + protected AccountNotificationHelper accountNotification; + + @Autowired + public RelationHelper(AccountNotificationHelper accountNotification) { + this.accountNotification = accountNotification; + } + + protected void createNewRelation(ImdgTransaction transaction, Company company) { + Relation relation = new Relation(); +// relation.setId(idSequence.nextId()); + relation.setCreated(Instant.now()); + relation.setUpdated(relation.getCreated()); + + relation.setConsumerId(company.getId()); + relation.setSupplierId(SPVB_ID); // 1 СПВБ + relation.setServiceStatus(WorkflowStatus.Active.getKey()); + 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); + relationMap.insert(relation); + } + + /** + * @param company + * @param oldStatus + * @param newStatus WorkflowStatus.Active - при возобналвении; WorkflowStatus.Blocked - при блокировки/расторжении + */ + public void onChangeWorkflowStatus(ImdgTransaction transaction, Company company, String oldStatus, String newStatus) throws ValidationException { + log.debug("Company id={} status changed from {} to {}", + company.getId(), oldStatus, company.getWorkflowStatus()); + assert Objects.equals(newStatus, company.getWorkflowStatus()); + String query = String.format("consumerId=%s", company.getId()); + Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + Collection relations = relationMap.getCollectionObjectsBySQL(query); + log.trace("Selected {} Relation by query: {}", relations.size(), query); + Instant now = Instant.now(); + for (Relation relation : relations) { + boolean modified = false; + if (WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { + if (!ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus())) { + relation.setServiceStatus(ServiceStatus.Reopened.getKey()); + modified = true; + } + } else if (WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus())) { + if (!ServiceStatus.Closed.equalsByKey(relation.getServiceStatus())) { + relation.setServiceStatus(ServiceStatus.Closed.getKey()); + modified = true; + } + } + if (modified) { + relation.setUpdated(now); + log.debug("Relation id={} updated", relation.getId()); + relationMap.update(relation); + } + } + + if (WorkflowStatus.Blocked.equalsByKey(newStatus)) { + // IV - сообщения на добавления документа расторжения договора + CompanyErrors hasError = accountNotification.accountTerminationNotification(company.getId()); + if (hasError != null) { + log.warn("Can not block company, cause error {}", hasError); + throw new ValidationException(hasError); + } + } + } + +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountTerminationRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountTerminationRequest.java new file mode 100644 index 000000000..75b351491 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountTerminationRequest.java @@ -0,0 +1,36 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class AccountTerminationRequest { + @JsonProperty + private String account; + @JsonProperty + private Long accountId; + @JsonProperty + private Long companyId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } +} From 8c43a6e4aec25a10ab1d293fb81c67500f345048 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 21:43:21 +0300 Subject: [PATCH 52/90] =?UTF-8?q?company-service:=20CompanyInfoService=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B2=D0=B0=D0=BB?= =?UTF-8?q?=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 --- .../validation/CompanyValidationConfig.java | 72 ++++++++++++++++-- .../config/validation/ValidationConfig.java | 10 ++- .../company/service/CompanyInfoService.java | 74 ++++++++++++++++--- .../company/service/CompanyService.java | 2 +- .../clearing/company/util/RequestHelper.java | 4 +- .../service/CompanyInfoServiceTest.java | 11 +++ .../platform/messaging/domain/Consts.java | 2 + 7 files changed, 153 insertions(+), 22 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java index 2d3a63605..00c928cd5 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java @@ -3,12 +3,11 @@ 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.platform.dictionary.CompanySymbolDictionary; -import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.clearing.platform.dictionary.*; 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.ClearingMemberCategoryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyInfoUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; @@ -55,11 +54,11 @@ public class CompanyValidationConfig { CompanySymbolDictionary.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.WrongFieldValue) - ); + ); }; } - @Bean("companyUpdateRequestValidator")//todo type of request + @Bean("companyUpdateRequestValidator") public Function companyUpdateRequestValidator(Map> imdgForValidation) { return companyNewRequest -> { ImdgValidationContext context = new ImdgValidationContext<>(); @@ -113,4 +112,67 @@ public class CompanyValidationConfig { }; } + + @Bean("CompanyInfoUpdateRequestValidator") + public Function companyInfoUpdateRequestValidator(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", + CompanyInfoUpdateRequest::getId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound, + company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), + + DictionaryPresentRule.instance("CorporationSoleType", + CompanyInfoUpdateRequest::getCorporationSoleType, + IMDGDistributedNames.Map_CorporationSoleTypeDictionary, + CorporationSoleTypeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, false), + DictionaryPresentRule.instance("CountryCode", + CompanyInfoUpdateRequest::getCountryCode, + IMDGDistributedNames.Map_CountryCodeDictionary, + CountryCodeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false), + DictionaryPresentRule.instance("ProfessionalSign", + CompanyInfoUpdateRequest::getProfessionalSign, + IMDGDistributedNames.Map_AllowedDictionary, + AllowedDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false), + DictionaryPresentRule.instance("legalKind", + CompanyInfoUpdateRequest::getLegalKind, + IMDGDistributedNames.Map_LegalKindDictionary, + LegalKindDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false), + DictionaryPresentRule.instance("organizationType", + CompanyInfoUpdateRequest::getOrganizationType, + IMDGDistributedNames.Map_OrganizationTypeDictionary, + OrganizationTypeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false), + DictionaryPresentRule.instance("residence", + CompanyInfoUpdateRequest::getResidence, + IMDGDistributedNames.Map_CountryCodeDictionary, + CountryCodeDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false) + + ); + }; + } } 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 06c9aadc6..17f450e90 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 @@ -6,9 +6,7 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.generated.ClearingMemberCategory; import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.classes.statics.data.profile.ProfileDocument; -import ru.clearing.platform.dictionary.ClearingCategoryDictionary; -import ru.clearing.platform.dictionary.ContactTypeDictionary; -import ru.clearing.platform.dictionary.DocumentTypeDictionary; +import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -38,6 +36,12 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, DocumentTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_CorporationSoleTypeDictionary, CorporationSoleTypeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_AllowedDictionary, AllowedDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); return imdg; 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 84fd283e4..00d9f92fa 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 @@ -6,48 +6,98 @@ 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.profile.CompanyInfo; +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.company.CompanyInfoUpdateRequest; 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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.validation.IValidator; + +import java.time.Instant; +import java.util.function.Function; @Service public class CompanyInfoService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); -// private final Imdg companyInfoMap; private final Imdg companyMap; protected final CompanyService companyService; + private final RequestHelper requestHelper; + private final ValidationHelper validationHelper; + final Function companyInfoUpdateRequestValidator; + final UserRoleVerification userRoleVerification; @Autowired public CompanyInfoService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider, CompanyService companyService) { + ImdgProvider imdgProvider, CompanyService companyService, + IMessageResolver messageResolver, ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, + @Qualifier("CompanyInfoUpdateRequestValidator") + Function companyInfoUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); this.companyService = companyService; -// this.companyInfoMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyInfo, CompanyInfo.class); this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; + this.requestHelper = new RequestHelper(log, messageResolver); + this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator; } @Override public void afterPropertiesSet() { callback(CompanyInfoUpdateRequest.class) - .setConsumer(this::companyInfoUpdate) + .setFunction(this::companyInfoUpdate) .forDestination(Consts.DESTINATION_COMPANY_INFO_UPDATE, callbacks::put); + callback(CompanyInfoUpdateRequest.class) + .setFunction(this::companyInfoUpdate) + .forDestination(Consts.DESTINATION_COMPANY_INFO_NEW, callbacks::put); // логика заполнения одинакова с companyInfoUpdate init(); } - public void companyInfoUpdate(BaseRequest userRequest) { - CompanyInfoUpdateRequest req = userRequest.getRequestPayload(); - log.debug("CompanyInfoUpdateRequest received"); + + protected void validateRole(BaseRequest req) throws ValidationException { + Long requestor = req.getUserId(); + if (requestor != null && !userRoleVerification.userHasRole(requestor, UserRole.Admin)) { + log.trace("User {} has no role to allow this action", requestor); + throw new ValidationException(CompanyErrors.UserVerifyDenial); + } else { + log.trace("Request without userId"); + } + } + + public RequestInfoUpdate companyInfoUpdate(BaseRequest companyInfoReq) { + CompanyInfoUpdateRequest req = companyInfoReq.getRequestPayload(); + log.debug("{} received", req.getClass().getSimpleName()); + { // Валидация, ValidationException + try { + validateRole(companyInfoReq); + } catch (ValidationException e) { + return requestHelper.makeErrorResponse(companyInfoReq, e.getEnumMsg()); + } + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyInfoReq, companyInfoUpdateRequestValidator); + if (requestInfoUpdate != null) + return requestInfoUpdate; + } synchronized (companyService) { -// CompanyInfo companyInfo = companyInfoMap.getSingleObjectByID(req.getId()); Company company = companyMap.getSingleObjectByID(req.getId()); - CompanyInfo companyInfo = company == null ? null : company.getProfile(); + if (company == null) { + log.trace("Company {} not found", req.getId()); + return requestHelper.makeErrorResponse(companyInfoReq, CompanyErrors.CompanyNotFound, companyInfoReq.getId()); + } + CompanyInfo companyInfo = company.getProfile(); companyInfo.setCorporationSoleType(req.getCorporationSoleType()); companyInfo.setCountryCode(req.getCountryCode()); @@ -60,9 +110,11 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea companyInfo.setFullNameEng(req.getFullNameEng()); companyInfo.setShortName(req.getShortName()); companyInfo.setFullName(req.getFullName()); -// companyInfoMap.update(companyInfo); + + company.setUpdated(Instant.now()); companyMap.update(company); - log.debug("successfully processed, id {}", companyInfo.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/CompanyService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java index ed1127656..798e4c72f 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 @@ -169,7 +169,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { } - private synchronized RequestInfoUpdate updateCompany(BaseRequest companyUpdateRequestBaseRequest) throws ValidationException { + private synchronized RequestInfoUpdate updateCompany(BaseRequest companyUpdateRequestBaseRequest) throws ValidationException { CompanyNewRequest updateRequest = companyUpdateRequestBaseRequest.getRequestPayload(); { // Валидация, ValidationException validateRole(companyUpdateRequestBaseRequest); 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 1b810e700..3e9bc8ad5 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 @@ -7,6 +7,7 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ClearingBaseException; import ru.spcex.platform.utils.log.ExceptionUtils; @@ -75,8 +76,7 @@ public class RequestHelper { } - public RequestInfoUpdate makeErrorResponse(BaseRequest request, IEnumId error, Object ... args) { - //todo должны уточнить интерфейс IEnumId в CompanyErrors, вечером проверить код. + public RequestInfoUpdate makeErrorResponse(BaseRequest request, IErrorEnumId error, Object ... args) { return makeErrorResponse(request, new EnumMessage(error, args)); } 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 baaf423ae..b420c42a6 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 @@ -56,6 +56,17 @@ class CompanyInfoServiceTest { private void init() { hazelcastServiceTest.waitAvailable(); companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + /* todo залить тестовые словари: + IMDGDistributedNames.Map_WorkflowStatusDictionary, DocumentTypeDictionary.class); +IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class); +IMDGDistributedNames.Map_CorporationSoleTypeDictionary, CorporationSoleTypeDictionary.class); +IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); +IMDGDistributedNames.Map_AllowedDictionary, AllowedDictionary.class); +IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class); +IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class); +IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); + */ } /** 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 69bfd494d..902f83e15 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 @@ -38,6 +38,7 @@ public interface Consts { String DESTINATION_COMPANY_DELETE = "company-delete"; String DESTINATION_COMPANY_UPDATE = "company-update"; String DESTINATION_COMPANY_BLOCK = "company-block"; + String DESTINATION_COMPANY_INFO_NEW = "company-info-new"; String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update"; String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update"; String DESTINATION_CONTACT_NEW = "contact-new"; @@ -67,6 +68,7 @@ public interface Consts { String SDF11_PROCESS = "sdf11-process"; String EXPORT_PROCESS = "export-process"; String ACCOUNT_NEW = "account-new"; + String ACCOUNT_TERMINATION = "account-termination"; String BALANCE_ACCOUNT_NEW = "balance-account-new"; String BALANCE_ACCOUNT_UPDATE = "balance-account-update"; String CONTINUE_CLEARING = "continue-clearing"; From cd093c81ebef3a451ce76b345b14f9bf1139aaef Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 5 Apr 2023 22:52:41 +0300 Subject: [PATCH 53/90] =?UTF-8?q?company-service:=20CompanyRoleSetService?= =?UTF-8?q?=20(=D0=B2=20=D0=A2=D0=97=20=D0=BD=D0=B5=20=D1=83=D0=BA=D0=B0?= =?UTF-8?q?=D0=B7=D0=B0=D0=BD=D1=8B=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81?= =?UTF-8?q?=D1=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CompanyRoleSetService.java | 149 ++++++++++++++++++ .../platform/messaging/domain/Consts.java | 3 + .../cud/company/CompanyRoleSetNewRequest.java | 36 +++++ 3 files changed, 188 insertions(+) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyRoleSetNewRequest.java 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 new file mode 100644 index 000000000..ee8cef564 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java @@ -0,0 +1,149 @@ +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.beans.factory.annotation.Qualifier; +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.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.CompanyRoleSetNewRequest; +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.UserRole; +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.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.validation.IValidator; + +import java.util.Map; + +@Service +public class CompanyRoleSetService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final RequestHelper requestHelper; + private final ImdgProvider imdgProvider; + // private final Imdg companyMap; + private final Imdg companyRoleSetMap; + private final ImdgId idSequence; + protected UserRoleVerification userRoleVerification; + protected IMessageResolver messageResolver; + + private ValidationHelper validationHelper; +// private Function companyNewRequestValidator; + + + @Autowired + public CompanyRoleSetService(Consumer kafkaQueue, Producer kafkaProducer, + ImdgProvider imdgProvider, + IMessageResolver messageResolver, + UserRoleVerification userRoleVerification, + ValidationHelper validationHelper +// @Qualifier("CompanyRoleSetRequestValidator") +// Function companyNewRequestValidator, + ) { + super(kafkaQueue, kafkaProducer); + this.imdgProvider = imdgProvider; + this.messageResolver = messageResolver; + this.requestHelper = new RequestHelper(log, messageResolver); + this.companyRoleSetMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); + this.idSequence = imdgProvider.getImdgIdGenerator(); + this.userRoleVerification = userRoleVerification; + this.validationHelper = validationHelper; +// this.companyDeleteRequestValidator = companyDeleteRequestValidator; + } + + @Override + public void afterPropertiesSet() { + callback(CompanyRoleSetNewRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::createCompanyRoleSet, request)) + .forDestination(Consts.DESTINATION_COMPANY_ROLE_SET_NEW, callbacks::put); +// callback(CompanyRoleSetNewRequest.class) +// .setConsumer(request -> requestHelper.requestFunction(this::createCompanyRoleSet, request)) +// .forDestination(Consts.DESTINATION_COMPANY_ROLE_SET_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::deleteCompanyRoleSet, request)) + .forDestination(Consts.DESTINATION_COMPANY_ROLE_SET_DELETE + , callbacks::put); + init(); + } + + protected void validateRole(BaseRequest req) throws ValidationException { + Long requestor = req.getUserId(); + if (requestor != null && !userRoleVerification.userHasRole(requestor, UserRole.Admin)) { + log.trace("User {} has no role to allow this action", requestor); + throw new ValidationException(CompanyErrors.UserVerifyDenial); + } else { + log.trace("Request without userId"); + } + } + + + private RequestInfoUpdate createCompanyRoleSet(BaseRequest companyRoleNewRequestBaseRequest) throws ValidationException { + CompanyRoleSetNewRequest req = companyRoleNewRequestBaseRequest.getRequestPayload(); + log.debug("companyroleset-new request received, BaseRequest.id = {}", companyRoleNewRequestBaseRequest.getId()); + { // Валидация, ValidationException + validateRole(companyRoleNewRequestBaseRequest); +// RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyRoleNewRequestBaseRequest, companyNewRequestValidator); +// if (requestInfoUpdate != null) return requestInfoUpdate; + } + //todo какие проверки нужны? 1. есть компания, 2. есть справочники + CompanyRoleSet newRole = companyRoleSetMap.getSingleObjectByFieldValues(Map.of( + "companyId", req.getCompanyId(), + "companyRole", req.getCompanyRole() + )); + + boolean isNew; + if (newRole == null) { + isNew = true; + newRole = new CompanyRoleSet(); + newRole.setId(idSequence.nextId()); + newRole.setCompanyId(req.getCompanyId()); + log.trace("New CompanyRoleSet[{}] for company {}", newRole.getId(), req.getCompanyId()); + } else { + isNew = false; + log.trace("Update exist CompanyRoleSet[{}] for company {}", newRole.getId(), req.getCompanyId()); +// return requestHelper.makeErrorResponse(companyRoleNewRequestBaseRequest, CompanyErrors.RecordAlreadyExist, newRole.getId()); + } + newRole.setCompanyRole(req.getCompanyRole()); + newRole.setWorkflowStatus(req.getWorkflowStatus()); + if (isNew) + companyRoleSetMap.insert(newRole); + else + companyRoleSetMap.update(newRole); + return null; + } + + + private RequestInfoUpdate deleteCompanyRoleSet(BaseRequest companyRoleSetDeleteRequest) throws ValidationException { + CommonDeleteRequest request = companyRoleSetDeleteRequest.getRequestPayload(); + log.debug("companyRoleSetDeleteRequest received id = {}", request.getId()); + { // Валидация, ValidationException + validateRole(companyRoleSetDeleteRequest); + if (request.getId() == null) { + return requestHelper.makeErrorResponse(companyRoleSetDeleteRequest, CompanyErrors.RequiredFieldEmpty, "id"); + } + } + CompanyRoleSet role = companyRoleSetMap.getSingleObjectByID(request.getId()); + if (role == null) { + return requestHelper.makeErrorResponse(companyRoleSetDeleteRequest, CompanyErrors.RecordNotFound, request.getId()); + } + companyRoleSetMap.delete(role); + log.debug("CompanyRoleSet {} for company {} delete", role.getId(), role.getCompanyId()); + return null; + } + +} 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 902f83e15..04e5545d4 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 @@ -41,6 +41,9 @@ public interface Consts { String DESTINATION_COMPANY_INFO_NEW = "company-info-new"; String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update"; String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update"; + String DESTINATION_COMPANY_ROLE_SET_NEW = "companyroleset-new"; + String DESTINATION_COMPANY_ROLE_SET_DELETE = "companyroleset-delete"; + String DESTINATION_COMPANY_ROLE_SET_UPDATE = "companyroleset-update"; String DESTINATION_CONTACT_NEW = "contact-new"; String DESTINATION_CONTACT_UPDATE = "contact-update"; String DESTINATION_CLEARING_MEMBER_CATEGORY_NEW = "clearing-member-category-new"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyRoleSetNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyRoleSetNewRequest.java new file mode 100644 index 000000000..4926bfeda --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyRoleSetNewRequest.java @@ -0,0 +1,36 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CompanyRoleSetNewRequest { + @JsonProperty + Long companyId; + @JsonProperty + String companyRole; + @JsonProperty + String workflowStatus; + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public String getCompanyRole() { + return companyRole; + } + + public void setCompanyRole(String companyRole) { + this.companyRole = companyRole; + } + + public String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } +} From eb4e730bdf93581d56e805109db5a5e0d4a52658 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Thu, 6 Apr 2023 10:13:17 +0300 Subject: [PATCH 54/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F=D0=BB=20Double=20=D0=BD?= =?UTF-8?q?=D0=B0=20BigDecimal=20=D0=B2=20=D0=BF=D0=BE=D0=BB=D1=8F=D1=85?= =?UTF-8?q?=20nominalValue=20=D0=B8=20lotSize.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../securities/MoneyMarketSecurityNewAction.java | 13 +++++++------ .../securities/MoneyMarketSecurityUpdateAction.java | 13 +++++++------ .../CudMoneyMarketSecurityControllerTest.java | 8 ++++---- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java index f96db5e09..4fd684ba6 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java @@ -13,6 +13,7 @@ import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.text.TextUtil; +import java.math.BigDecimal; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; @@ -32,7 +33,7 @@ public class MoneyMarketSecurityNewAction implements IAction validate() { @@ -107,11 +108,11 @@ public class MoneyMarketSecurityNewAction implements IAction Date: Thu, 6 Apr 2023 10:13:59 +0300 Subject: [PATCH 55/90] IsLongValueRule --- .../common/rules/IsLongValueRule.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java new file mode 100644 index 000000000..a5dcdd328 --- /dev/null +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java @@ -0,0 +1,66 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка поля типа String на возможность преобразования в Long + * + * @param Класс проверяемого объекта + */ +public record IsLongValueRule( + String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredField, + IErrorEnumId errorWrongFieldValue, + boolean required +) implements IValidationRule> { + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемого поля + * @param errorEmptyRequiredField Ошибка, которая будет возвращена, если поле пустое + * @param errorWrongFieldValue Ошибка, которая будет возвращена, если поле нельзя преобразовать в Long + * @param required Флаг обязательности поля + * @param Класс проверяемого объекта + */ + public static IsLongValueRule instance(String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredField, + IErrorEnumId errorWrongFieldValue, + boolean required) { + return new IsLongValueRule<>(fieldName, getter, errorEmptyRequiredField, errorWrongFieldValue, required); + } + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемого поля + * @param errorEmptyRequiredField Ошибка, которая будет возвращена, если поле пустое + * @param errorWrongFieldValue Ошибка, которая будет возвращена, если поле нельзя преобразовать в Long + * @param Класс проверяемого объекта + */ + public static IsLongValueRule instance(String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredField, + IErrorEnumId errorWrongFieldValue) { + return new IsLongValueRule<>(fieldName, getter, errorEmptyRequiredField, errorWrongFieldValue, true); + } + + @Override + public Optional validate(ImdgValidationContext context) { + R validatedObject = context.getValidatedObject(); + String longValueStr = getter.apply(validatedObject); + if (longValueStr == null) return required ? of(errorEmptyRequiredField, fieldName) : Optional.empty(); + try { + Long longValue = Long.valueOf(longValueStr); + } catch (NumberFormatException e) { + return of(errorWrongFieldValue, fieldName); + } + return Optional.empty(); + } +} From a45445340a1d0986a85db522b0c0a8891b820336 Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 10:27:41 +0300 Subject: [PATCH 56/90] FieldRequiredRule add additionalChecks --- .../common/rules/FieldRequiredRule.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index 370f0147d..475e16e77 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -18,7 +18,8 @@ import java.util.function.Function; public record FieldRequiredRule( String fieldName, Function getter, - IErrorEnumId errorEmptyRequiredValue + IErrorEnumId errorEmptyRequiredValue, + Function[] additionalChecks ) implements IValidationRule> { /** @@ -28,9 +29,12 @@ public record FieldRequiredRule( * @param Класс проверяемого объекта * @param Класс проверяемого значения */ - public static FieldRequiredRule instance(String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue) { + public static FieldRequiredRule instance(String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredValue, + Function ... additionalChecks) { if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); - return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue); + return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue, additionalChecks); } @Override @@ -38,6 +42,11 @@ public record FieldRequiredRule( R validatedObject = context.getValidatedObject(); V value = getter.apply(validatedObject); if (value == null) return of(errorEmptyRequiredValue, fieldName); + for (Function additionalCheck : additionalChecks) { + IErrorEnumId validationError = additionalCheck.apply(value); + if (validationError != null) + return of(validationError, fieldName); + } return empty(); } From 156e181d5069c9e1c58e172d0ef6c2f1db9e47da Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 10:32:24 +0300 Subject: [PATCH 57/90] FieldRequiredRule fix --- .../validation/common/rules/FieldRequiredRule.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index 475e16e77..d8e0a0303 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -19,7 +19,7 @@ public record FieldRequiredRule( String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue, - Function[] additionalChecks + Function[] additionalChecks ) implements IValidationRule> { /** @@ -32,7 +32,7 @@ public record FieldRequiredRule( public static FieldRequiredRule instance(String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue, - Function ... additionalChecks) { + Function ... additionalChecks) { if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue, additionalChecks); } @@ -42,8 +42,8 @@ public record FieldRequiredRule( R validatedObject = context.getValidatedObject(); V value = getter.apply(validatedObject); if (value == null) return of(errorEmptyRequiredValue, fieldName); - for (Function additionalCheck : additionalChecks) { - IErrorEnumId validationError = additionalCheck.apply(value); + for (Function additionalCheck : additionalChecks) { + IErrorEnumId validationError = additionalCheck.apply(validatedObject); if (validationError != null) return of(validationError, fieldName); } From 09c0ab342b677f8c6a1c13ca14d3b3462539570d Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 10:37:48 +0300 Subject: [PATCH 58/90] FixedIncomeCashFlowValidationConfig --- .../common/rules/FieldRequiredRule.java | 1 + .../ClearingMemberCategoryService.java | 4 +- .../securities/config/ValidationConfig.java | 19 ++++++ .../FixedIncomeCashFlowValidationConfig.java | 64 ++++++++++++++++++ .../cud/FixedIncomeCashFlowService.java | 65 +++++++++++++++++++ 5 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index d8e0a0303..2cef88c89 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -29,6 +29,7 @@ public record FieldRequiredRule( * @param Класс проверяемого объекта * @param Класс проверяемого значения */ + @SafeVarargs public static FieldRequiredRule instance(String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue, 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 e3e928473..56c7335ad 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 @@ -65,12 +65,12 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init } private RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { - ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); + log.debug("ClearingMemberCategoryNewRequest received {}", userRequest.getId()); RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryNewRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; - log.debug("ClearingMemberCategoryUpdateRequest received {}", userRequest.getId()); + ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); ClearingMemberCategory newCategory = new ClearingMemberCategory(); newCategory.setCompanyId(req.getCompanyId()); newCategory.setClearingMemberCategory(req.getClearingMemberCategory()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java index 253f2395c..6fcd1fcf6 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java @@ -2,13 +2,32 @@ package ru.spcex.clearing.securities.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import ru.clearing.platform.dictionary.CountryCodeDictionary; +import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; + @Configuration public class ValidationConfig { + @Bean("imdgForValidation") + public Map> imdgForValidation(ImdgProvider imdgProvider) { + final Map> imdg = new HashMap<>(); + BiConsumer> addImdg = (s, aClass) -> imdg.put(s, imdgProvider.getImdg(s, aClass)); + + addImdg.accept(IMDGDistributedNames.Map_FixedIncomeCashFlow, CountryCodeDictionary.class); + + return imdg; + } + @Bean("validationHelper") public ValidationHelper validationHelper(IMessageResolver messageResolver) { return new ValidationHelper(messageResolver); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java new file mode 100644 index 000000000..179b29106 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java @@ -0,0 +1,64 @@ +package ru.spcex.clearing.securities.config.validation; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeCashFlow; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowNewRequest; +import ru.spcex.clearing.securities.errors.SecuritiesError; +import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; +import ru.spcex.clearing.validation.common.rules.IsLongValueRule; +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.Collection; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +@Configuration +public class FixedIncomeCashFlowValidationConfig { + + @Bean("fixedIncomeCashFlowNewRequestValidator") + public Function fixedIncomeCashFlowNewRequestValidator( + Map> imdgForValidation + ) { + return fixedIncomeCashFlowNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(fixedIncomeCashFlowNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); + return new ValidatorImpl<>(context, + IsLongValueRule.instance("securitySymbol", + FixedIncomeCashFlowNewRequest::getSecuritySymbol, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue), + FieldRequiredRule.instance("securitySymbol", + FixedIncomeCashFlowNewRequest::getSecuritySymbol, + SecuritiesError.RequiredFieldIsEmpty, + request -> { + Imdg fixedIncomeCashFlowImdg = context.obtainMap( + IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class + ); + Long securityId = Long.valueOf(request.getSecuritySymbol()); + Collection fixedIncomeCashFlows = fixedIncomeCashFlowImdg.getCollectionObjectsByFieldValues(Map.of("securityId", securityId)); + if (!fixedIncomeCashFlows.isEmpty()) return SecuritiesError.CouponPeriodAlreadyExists; + return null; + }), + FieldRequiredRule.instance("accruedCoupon", + FixedIncomeCashFlowNewRequest::getAccruedCoupon, + SecuritiesError.RequiredFieldIsEmpty), + FieldRequiredRule.instance("nominalValue", + FixedIncomeCashFlowNewRequest::getNominalValue, + SecuritiesError.RequiredFieldIsEmpty), + FieldRequiredRule.instance("number", + FixedIncomeCashFlowNewRequest::getNumber, + SecuritiesError.RequiredFieldIsEmpty) + ); + }; + } + +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java new file mode 100644 index 000000000..b8309e587 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java @@ -0,0 +1,65 @@ +package ru.spcex.clearing.securities.service.cud; + +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.clearing.classes.statics.data.instrument.issue.FixedIncomeCashFlow; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowNewRequest; +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.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +@Service +public class FixedIncomeCashFlowService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg fixedIncomeCashFlowImdg; + private final ImdgProvider imdgProvider; + private final ValidationHelper validationHelper; + + public FixedIncomeCashFlowService(Consumer kafkaQueue, + Producer kafkaResponseQueue, + ImdgProvider imdgProvider, + ValidationHelper validationHelper) { + super(kafkaQueue, kafkaResponseQueue); + this.imdgProvider = imdgProvider; + this.validationHelper = validationHelper; + this.fixedIncomeCashFlowImdg = imdgProvider.getImdg( + IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class + ); + + } + + @Override + public void afterPropertiesSet() throws Exception { + log.debug("EquitySecurityNewRequest received"); + + init(); + } + + public RequestInfoUpdate fixedIncomeCashFlowNew(BaseRequest userRequest) { + log.debug("FixedIncomeCashFlowNewRequest received {}", userRequest.getId()); + + // validation + + FixedIncomeCashFlowNewRequest req = userRequest.getRequestPayload(); + FixedIncomeCashFlow fixedIncomeCashFlow = new FixedIncomeCashFlow(); + fixedIncomeCashFlow.setSecurityId(Long.valueOf(req.getSecuritySymbol())); + fixedIncomeCashFlow.setAccruedCoupon(req.getAccruedCoupon()); + fixedIncomeCashFlow.setNominalValue(req.getNominalValue()); + fixedIncomeCashFlow.setNumber(req.getNumber()); + fixedIncomeCashFlow.setValueDate(req.getValueDate()); + + Long id = fixedIncomeCashFlowImdg.insert(fixedIncomeCashFlow); + log.debug("successfully processed, id {}", id); + + return null; + } +} + From bacbf1cecab1a986e7a5836a81090af1574c70e6 Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 10:46:50 +0300 Subject: [PATCH 59/90] add Consts (FixedIncomeCashFlow) --- .../cud/FixedIncomeCashFlowService.java | 21 ++++++++++++++----- .../platform/messaging/domain/Consts.java | 3 +++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java index b8309e587..bf227b425 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java @@ -5,48 +5,59 @@ 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.instrument.issue.FixedIncomeCashFlow; 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.securitites.FixedIncomeCashFlowNewRequest; 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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.validation.IValidator; + +import java.util.function.Function; @Service -public class FixedIncomeCashFlowService extends QueueConsumer implements InitializingBean { +public class FixedIncomeCashFlowService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg fixedIncomeCashFlowImdg; private final ImdgProvider imdgProvider; private final ValidationHelper validationHelper; + private final Function fixedIncomeCashFlowNewRequestValidator; + public FixedIncomeCashFlowService(Consumer kafkaQueue, Producer kafkaResponseQueue, ImdgProvider imdgProvider, - ValidationHelper validationHelper) { + ValidationHelper validationHelper, + @Qualifier("fixedIncomeCashFlowNewRequestValidator") Function fixedIncomeCashFlowNewRequestValidator) { super(kafkaQueue, kafkaResponseQueue); this.imdgProvider = imdgProvider; this.validationHelper = validationHelper; + this.fixedIncomeCashFlowNewRequestValidator = fixedIncomeCashFlowNewRequestValidator; this.fixedIncomeCashFlowImdg = imdgProvider.getImdg( IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class ); - } @Override public void afterPropertiesSet() throws Exception { log.debug("EquitySecurityNewRequest received"); - + callback(FixedIncomeCashFlowNewRequest.class) + .setConsumer(this::fixedIncomeCashFlowNew) + .forDestination(Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_NEW, callbacks::put); init(); } public RequestInfoUpdate fixedIncomeCashFlowNew(BaseRequest userRequest) { log.debug("FixedIncomeCashFlowNewRequest received {}", userRequest.getId()); - // validation + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, fixedIncomeCashFlowNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; FixedIncomeCashFlowNewRequest req = userRequest.getRequestPayload(); FixedIncomeCashFlow fixedIncomeCashFlow = new FixedIncomeCashFlow(); 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 04e5545d4..2a235f2d0 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 @@ -13,6 +13,9 @@ public interface Consts { String DESTINATION_FIXED_INCOME_SECURITY_UPDATE = "fixed-income-security-update"; String DESTINATION_FIXED_INCOME_SECURITY_DELETE = "fixed-income-security-delete"; + String DESTINATION_FIXED_INCOME_CASH_FLOW_NEW = "fixed-income-cash-flow-new"; + String DESTINATION_FIXED_INCOME_CASH_FLOW_UPDATE = "fixed-income-cash-flow-update"; + String DESTINATION_CURRENCY_NEW = "currency-new"; String DESTINATION_CURRENCY_UPDATE = "currency-update"; String DESTINATION_COUPON_PERIOD_NEW = "coupon_period-new"; From 21db7fb5bd582d48a13bb5046d9b7bb671547e0d Mon Sep 17 00:00:00 2001 From: psemenkov Date: Thu, 6 Apr 2023 10:50:34 +0300 Subject: [PATCH 60/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D0=B4=D1=83=D0=B1=D0=BB?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0=D1=82=20EndDtAfterStartDt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/ValidationProvider.java | 23 ++++++++++-- .../rule/CouponPeriodNewValidationRule.java | 11 ------ .../CouponPeriodUpdateValidationRule.java | 11 ------ .../validation/rule/EndDtAfterStartDt.java | 35 ------------------- 4 files changed, 21 insertions(+), 59 deletions(-) delete mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EndDtAfterStartDt.java diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index a8a055fd3..6aedc564f 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -6,6 +6,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteReques import ru.spcex.clearing.platform.messaging.domain.cud.securitites.*; import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.clearing.securities.validation.rule.*; +import ru.spcex.clearing.validation.common.rules.EndDtAfterStartDtRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -58,7 +59,11 @@ public class ValidationProvider { context.addImdg(IMDGDistributedNames.Map_TermTypeDictionary, termTypeDictionaryImdg); context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg); return new ValidatorImpl<>(context, - EndDtAfterStartDt.instance(MoneyMarketSecurityNewRequest.class), + EndDtAfterStartDtRule.instance("startDate", "endDate", + MoneyMarketSecurityNewRequest::getStartDate, + MoneyMarketSecurityNewRequest::getEndDate, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue), new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentAlreadyExists, MoneyMarketSecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "RATE"), MmsNewValidationRule.RequiredFieldIsNotEmpty, @@ -82,7 +87,11 @@ public class ValidationProvider { context.addImdg(IMDGDistributedNames.Map_TermTypeDictionary, termTypeDictionaryImdg); context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg); return new ValidatorImpl<>(context, - EndDtAfterStartDt.instance(MoneyMarketSecurityUpdateRequest.class), + EndDtAfterStartDtRule.instance("startDate", "endDate", + MoneyMarketSecurityUpdateRequest::getStartDate, + MoneyMarketSecurityUpdateRequest::getEndDate, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), new WorkflowStatusActv(), @@ -250,6 +259,11 @@ public class ValidationProvider { context.setValidatedObject(currencyRequest); context.addImdg(IMDGDistributedNames.Map_CouponPeriod, couponPeriodImdg); return new ValidatorImpl<>(context, + EndDtAfterStartDtRule.instance("periodStartDate", "periodEndDate", + CouponPeriodNewRequest::getPeriodStartDate, + CouponPeriodNewRequest::getPeriodEndDate, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue, false), CouponPeriodNewValidationRule.CouponPeriodNotExists ); }; @@ -261,6 +275,11 @@ public class ValidationProvider { context.setValidatedObject(currencyRequest); context.addImdg(IMDGDistributedNames.Map_CouponPeriod, couponPeriodImdg); return new ValidatorImpl<>(context, + EndDtAfterStartDtRule.instance("periodStartDate", "periodEndDate", + CouponPeriodUpdateRequest::getPeriodStartDate, + CouponPeriodUpdateRequest::getPeriodEndDate, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue, false), CouponPeriodUpdateValidationRule.CouponPeriodExists ); }; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java index 7a95f7298..9546037e3 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java @@ -26,17 +26,6 @@ public enum CouponPeriodNewValidationRule implements IValidationRule implements IValidationRule> { - - public EndDtAfterStartDt() {} - - public static EndDtAfterStartDt instance(Class clazz) { - return new EndDtAfterStartDt<>(); - } - - @Override - public Optional validate(ImdgValidationContext context) { - T validatedObject = context.getValidatedObject(); - if(validatedObject.getEndDate() == null && validatedObject.getStartDate() == null) { - return of(SecuritiesError.RequiredFieldIsEmpty, "endDate", "startDate"); - } - if(validatedObject.getEndDate() == null || validatedObject.getStartDate() == null){ - if(validatedObject.getStartDate() == null) return of(SecuritiesError.RequiredFieldIsEmpty, "startDate"); - return of(SecuritiesError.RequiredFieldIsEmpty, "endDate"); - } - if (validatedObject.getEndDate().isBefore(validatedObject.getStartDate())) { - return of(SecuritiesError.WrongFieldValue, "endDate"); - } - return empty(); - } -} From 7a3c1ec22c59613e76472c27bd522441c253803c Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 11:09:54 +0300 Subject: [PATCH 61/90] FixedIncomeCashFlow, new request test --- .../FixedIncomeCashFlowValidationConfig.java | 2 +- .../securities/config/ImdgTestConfig.java | 2 + .../FixedIncomeCashFlowServiceTest.java | 113 ++++++++++++++++++ .../FixedIncomeCashFlowNewRequest.java | 5 + 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java index 179b29106..04dcc1b6d 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java @@ -30,7 +30,7 @@ public class FixedIncomeCashFlowValidationConfig { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(fixedIncomeCashFlowNewRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); - addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); + addImdg.accept(IMDGDistributedNames.Map_FixedIncomeCashFlow); return new ValidatorImpl<>(context, IsLongValueRule.instance("securitySymbol", FixedIncomeCashFlowNewRequest::getSecuritySymbol, diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java index 95f01963c..839542afd 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java @@ -15,10 +15,12 @@ import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper; import java.util.List; import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; @Configuration public class ImdgTestConfig { + public static final AtomicLong currentID = new AtomicLong(0L); private HazelcastInstance hazelcastInstance; private static ThreadPoolTaskExecutor createThreadPoolTestTaskExecutor(int maxPoolSz, boolean waitForCompletion) { diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java new file mode 100644 index 000000000..27fc8ce30 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java @@ -0,0 +1,113 @@ +package ru.spcex.clearing.securities.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.instrument.issue.FixedIncomeCashFlow; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowNewRequest; +import ru.spcex.clearing.securities.config.ErrorResolverConfig; +import ru.spcex.clearing.securities.config.ImdgTestConfig; +import ru.spcex.clearing.securities.config.KafkaTestConfig; +import ru.spcex.clearing.securities.config.ValidationConfig; +import ru.spcex.clearing.securities.config.validation.FixedIncomeCashFlowValidationConfig; +import ru.spcex.clearing.securities.service.cud.FixedIncomeCashFlowService; +import ru.spcex.clearing.securities.utils.MatcherFactory.Matcher; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.time.LocalDate; + +import static ru.spcex.clearing.securities.config.ImdgTestConfig.currentID; +import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.securities.utils.TestUtils.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + ErrorResolverConfig.class, + ValidationConfig.class, + FixedIncomeCashFlowService.class, + FixedIncomeCashFlowValidationConfig.class, + KafkaTestConfig.class, + ImdgTestConfig.class}) +class FixedIncomeCashFlowServiceTest { + public static final Matcher FIXED_INCOME_CASH_FLOW_MATCHER = usingIgnoringFieldsComparator(); + + private static final String TOPIC_FIXED_INCOME_CASH_FLOW_NEW = Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_NEW; + private static final String TOPIC_FIXED_INCOME_CASH_FLOW_UPDATE = Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_UPDATE; + private static final Long ID = currentID.incrementAndGet(); + private static final int PARTITION = 0; + + @Autowired + FixedIncomeCashFlowService fixedIncomeCashFlowService; + + @Autowired + @Qualifier("hazelcastServiceTest") + private ImdgProvider hazelcastServiceTest; + private Imdg fixedIncomeCashFlowImdg; + + @Captor + private ArgumentCaptor producerRecord; + @SpyBean + private MockProducer mockProducer; + + private final String SECURITY_SYMBOL_STR = "777"; + private final Long SECURITY_SYMBOL_LONG = 777L; + + private final LocalDate TEST_DATE = LocalDate.now(); + + private final BigDecimal TEST_BIG_DECIMAL = BigDecimal.TEN; + + private final Long TEST_LONG = Long.MAX_VALUE; + + @PostConstruct + private void init() { + hazelcastServiceTest.waitAvailable(); + fixedIncomeCashFlowImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_FixedIncomeCashFlow, + FixedIncomeCashFlow.class + ); + } + + @Test + void fixedIncomeCashFlowNewTest() throws InterruptedException { + //ARRANGE + FixedIncomeCashFlowNewRequest newRequest = new FixedIncomeCashFlowNewRequest(); + newRequest.setSecuritySymbol(SECURITY_SYMBOL_STR); + newRequest.setNominalValue(TEST_BIG_DECIMAL); + newRequest.setAccruedCoupon(TEST_BIG_DECIMAL); + newRequest.setNumber(TEST_LONG); + newRequest.setValueDate(TEST_DATE); + + FixedIncomeCashFlow predictableFixedIncomeCashFlow = new FixedIncomeCashFlow(); + predictableFixedIncomeCashFlow.setSecurityId(SECURITY_SYMBOL_LONG); + predictableFixedIncomeCashFlow.setNominalValue(TEST_BIG_DECIMAL); + predictableFixedIncomeCashFlow.setAccruedCoupon(TEST_BIG_DECIMAL); + predictableFixedIncomeCashFlow.setNumber(TEST_LONG); + predictableFixedIncomeCashFlow.setValueDate(TEST_DATE); + + //ACT + String jsonString = getJsonStringForNew(newRequest, ID); + + addRecordToKafka((MockConsumer) fixedIncomeCashFlowService.getConsumer(), TOPIC_FIXED_INCOME_CASH_FLOW_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + FixedIncomeCashFlow resultNew = fixedIncomeCashFlowImdg.getSingleObjectBySQL(String.format("securityId = %s", SECURITY_SYMBOL_STR)); + predictableFixedIncomeCashFlow.setId(resultNew.getId()); + FIXED_INCOME_CASH_FLOW_MATCHER.assertMatch(resultNew, predictableFixedIncomeCashFlow); + } + +} \ No newline at end of file diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java index eaca2e32b..dc4ae3c0e 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java @@ -2,7 +2,10 @@ package ru.spcex.clearing.platform.messaging.domain.cud.securitites; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; import java.math.BigDecimal; @@ -24,6 +27,8 @@ public class FixedIncomeCashFlowNewRequest implements WithSecuritySymbol { public Long number; @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate valueDate; From 398307b6b546f6d2baafeec36c217801d83655d1 Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 11:16:12 +0300 Subject: [PATCH 62/90] FieldRequiredRule fix --- .../common/rules/FieldRequiredRule.java | 8 ++-- .../FixedIncomeCashFlowValidationConfig.java | 43 ++++++++++++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index 2cef88c89..b9f5bb89c 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -19,7 +19,7 @@ public record FieldRequiredRule( String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue, - Function[] additionalChecks + Function[] additionalChecks ) implements IValidationRule> { /** @@ -33,7 +33,7 @@ public record FieldRequiredRule( public static FieldRequiredRule instance(String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue, - Function ... additionalChecks) { + Function ... additionalChecks) { if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue, additionalChecks); } @@ -43,8 +43,8 @@ public record FieldRequiredRule( R validatedObject = context.getValidatedObject(); V value = getter.apply(validatedObject); if (value == null) return of(errorEmptyRequiredValue, fieldName); - for (Function additionalCheck : additionalChecks) { - IErrorEnumId validationError = additionalCheck.apply(validatedObject); + for (Function additionalCheck : additionalChecks) { + IErrorEnumId validationError = additionalCheck.apply(value); if (validationError != null) return of(validationError, fieldName); } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java index 04dcc1b6d..cded567f6 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java @@ -39,11 +39,11 @@ public class FixedIncomeCashFlowValidationConfig { FieldRequiredRule.instance("securitySymbol", FixedIncomeCashFlowNewRequest::getSecuritySymbol, SecuritiesError.RequiredFieldIsEmpty, - request -> { + securitySymbol -> { Imdg fixedIncomeCashFlowImdg = context.obtainMap( IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class ); - Long securityId = Long.valueOf(request.getSecuritySymbol()); + Long securityId = Long.valueOf(securitySymbol); Collection fixedIncomeCashFlows = fixedIncomeCashFlowImdg.getCollectionObjectsByFieldValues(Map.of("securityId", securityId)); if (!fixedIncomeCashFlows.isEmpty()) return SecuritiesError.CouponPeriodAlreadyExists; return null; @@ -61,4 +61,43 @@ public class FixedIncomeCashFlowValidationConfig { }; } +// @Bean("fixedIncomeCashFlowUpdateRequestValidator") +// public Function fixedIncomeCashFlowUpdateRequestValidator( +// Map> imdgForValidation +// ) { +// return fixedIncomeCashFlowUpdateRequest -> { +// ImdgValidationContext context = new ImdgValidationContext<>(); +// context.setValidatedObject(fixedIncomeCashFlowUpdateRequest); +// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); +// addImdg.accept(IMDGDistributedNames.Map_FixedIncomeCashFlow); +// return new ValidatorImpl<>(context, +// IsLongValueRule.instance("securitySymbol", +// FixedIncomeCashFlowNewRequest::getSecuritySymbol, +// SecuritiesError.RequiredFieldIsEmpty, +// SecuritiesError.WrongFieldValue), +// FieldRequiredRule.instance("securitySymbol", +// FixedIncomeCashFlowNewRequest::getSecuritySymbol, +// SecuritiesError.RequiredFieldIsEmpty, +// request -> { +// Imdg fixedIncomeCashFlowImdg = context.obtainMap( +// IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class +// ); +// Long securityId = Long.valueOf(request.getSecuritySymbol()); +// Collection fixedIncomeCashFlows = fixedIncomeCashFlowImdg.getCollectionObjectsByFieldValues(Map.of("securityId", securityId)); +// if (!fixedIncomeCashFlows.isEmpty()) return SecuritiesError.CouponPeriodAlreadyExists; +// return null; +// }), +// FieldRequiredRule.instance("accruedCoupon", +// FixedIncomeCashFlowNewRequest::getAccruedCoupon, +// SecuritiesError.RequiredFieldIsEmpty), +// FieldRequiredRule.instance("nominalValue", +// FixedIncomeCashFlowNewRequest::getNominalValue, +// SecuritiesError.RequiredFieldIsEmpty), +// FieldRequiredRule.instance("number", +// FixedIncomeCashFlowNewRequest::getNumber, +// SecuritiesError.RequiredFieldIsEmpty) +// ); +// }; +// } + } From 61953777e6363356b2f24098c51b3abfc2bc8cdf Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 11:36:03 +0300 Subject: [PATCH 63/90] FixedIncomeCashFlow update request and test --- .../FixedIncomeCashFlowValidationConfig.java | 72 +++++++++---------- .../cud/FixedIncomeCashFlowService.java | 29 +++++++- .../FixedIncomeCashFlowServiceTest.java | 40 +++++++++++ .../FixedIncomeCashFlowUpdateRequest.java | 5 ++ 4 files changed, 106 insertions(+), 40 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java index cded567f6..815d779bf 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java @@ -5,8 +5,10 @@ import org.springframework.context.annotation.Configuration; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeCashFlow; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowUpdateRequest; import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; +import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IsLongValueRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; @@ -50,7 +52,7 @@ public class FixedIncomeCashFlowValidationConfig { }), FieldRequiredRule.instance("accruedCoupon", FixedIncomeCashFlowNewRequest::getAccruedCoupon, - SecuritiesError.RequiredFieldIsEmpty), + SecuritiesError.RequiredFieldIsEmpty), FieldRequiredRule.instance("nominalValue", FixedIncomeCashFlowNewRequest::getNominalValue, SecuritiesError.RequiredFieldIsEmpty), @@ -61,43 +63,35 @@ public class FixedIncomeCashFlowValidationConfig { }; } -// @Bean("fixedIncomeCashFlowUpdateRequestValidator") -// public Function fixedIncomeCashFlowUpdateRequestValidator( -// Map> imdgForValidation -// ) { -// return fixedIncomeCashFlowUpdateRequest -> { -// ImdgValidationContext context = new ImdgValidationContext<>(); -// context.setValidatedObject(fixedIncomeCashFlowUpdateRequest); -// Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); -// addImdg.accept(IMDGDistributedNames.Map_FixedIncomeCashFlow); -// return new ValidatorImpl<>(context, -// IsLongValueRule.instance("securitySymbol", -// FixedIncomeCashFlowNewRequest::getSecuritySymbol, -// SecuritiesError.RequiredFieldIsEmpty, -// SecuritiesError.WrongFieldValue), -// FieldRequiredRule.instance("securitySymbol", -// FixedIncomeCashFlowNewRequest::getSecuritySymbol, -// SecuritiesError.RequiredFieldIsEmpty, -// request -> { -// Imdg fixedIncomeCashFlowImdg = context.obtainMap( -// IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class -// ); -// Long securityId = Long.valueOf(request.getSecuritySymbol()); -// Collection fixedIncomeCashFlows = fixedIncomeCashFlowImdg.getCollectionObjectsByFieldValues(Map.of("securityId", securityId)); -// if (!fixedIncomeCashFlows.isEmpty()) return SecuritiesError.CouponPeriodAlreadyExists; -// return null; -// }), -// FieldRequiredRule.instance("accruedCoupon", -// FixedIncomeCashFlowNewRequest::getAccruedCoupon, -// SecuritiesError.RequiredFieldIsEmpty), -// FieldRequiredRule.instance("nominalValue", -// FixedIncomeCashFlowNewRequest::getNominalValue, -// SecuritiesError.RequiredFieldIsEmpty), -// FieldRequiredRule.instance("number", -// FixedIncomeCashFlowNewRequest::getNumber, -// SecuritiesError.RequiredFieldIsEmpty) -// ); -// }; -// } + @Bean("fixedIncomeCashFlowUpdateRequestValidator") + public Function fixedIncomeCashFlowUpdateRequestValidator( + Map> imdgForValidation + ) { + return fixedIncomeCashFlowUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(fixedIncomeCashFlowUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_FixedIncomeCashFlow); + return new ValidatorImpl<>(context, + IsLongValueRule.instance("securitySymbol", + FixedIncomeCashFlowUpdateRequest::getSecuritySymbol, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue, + false), + IdPresentRule.instance("id", + FixedIncomeCashFlowUpdateRequest::getId, + IMDGDistributedNames.Map_FixedIncomeCashFlow, + FixedIncomeCashFlow.class, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.CouponPeriodNotFound, + fixedIncomeCashFlow -> { + if (fixedIncomeCashFlowUpdateRequest.getSecuritySymbol() == null) return null; + if (!fixedIncomeCashFlowUpdateRequest.getSecuritySymbol().equalsIgnoreCase(String.valueOf(fixedIncomeCashFlow.getSecurityId()))) + return SecuritiesError.WrongFieldValue; + return null; + }) + ); + }; + } } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java index bf227b425..ab17cf7ed 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java @@ -12,6 +12,7 @@ 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.securitites.FixedIncomeCashFlowNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.validation.common.ValidationHelper; @@ -29,16 +30,19 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial private final ValidationHelper validationHelper; private final Function fixedIncomeCashFlowNewRequestValidator; + private final Function fixedIncomeCashFlowUpdateRequestValidator; public FixedIncomeCashFlowService(Consumer kafkaQueue, Producer kafkaResponseQueue, ImdgProvider imdgProvider, ValidationHelper validationHelper, - @Qualifier("fixedIncomeCashFlowNewRequestValidator") Function fixedIncomeCashFlowNewRequestValidator) { + @Qualifier("fixedIncomeCashFlowNewRequestValidator") Function fixedIncomeCashFlowNewRequestValidator, + @Qualifier("fixedIncomeCashFlowUpdateRequestValidator") Function fixedIncomeCashFlowUpdateRequestValidator) { super(kafkaQueue, kafkaResponseQueue); this.imdgProvider = imdgProvider; this.validationHelper = validationHelper; this.fixedIncomeCashFlowNewRequestValidator = fixedIncomeCashFlowNewRequestValidator; + this.fixedIncomeCashFlowUpdateRequestValidator = fixedIncomeCashFlowUpdateRequestValidator; this.fixedIncomeCashFlowImdg = imdgProvider.getImdg( IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class ); @@ -50,6 +54,9 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial callback(FixedIncomeCashFlowNewRequest.class) .setConsumer(this::fixedIncomeCashFlowNew) .forDestination(Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_NEW, callbacks::put); + callback(FixedIncomeCashFlowUpdateRequest.class) + .setConsumer(this::fixedIncomeCashFlowUpdate) + .forDestination(Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_UPDATE, callbacks::put); init(); } @@ -72,5 +79,25 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial return null; } + + public RequestInfoUpdate fixedIncomeCashFlowUpdate(BaseRequest userRequest) { + log.debug("FixedIncomeCashFlowUpdateRequest received {}", userRequest.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, fixedIncomeCashFlowUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + FixedIncomeCashFlowUpdateRequest req = userRequest.getRequestPayload(); + FixedIncomeCashFlow fixedIncomeCashFlow = fixedIncomeCashFlowImdg.getSingleObjectByID(req.getId()); + + if (req.getAccruedCoupon() != null) fixedIncomeCashFlow.setAccruedCoupon(req.getAccruedCoupon()); + if (req.getNominalValue() != null) fixedIncomeCashFlow.setNominalValue(req.getNominalValue()); + if (req.getNumber() != null) fixedIncomeCashFlow.setNumber(req.getNumber()); + if (req.getValueDate() != null) fixedIncomeCashFlow.setValueDate(req.getValueDate()); + + fixedIncomeCashFlowImdg.update(fixedIncomeCashFlow); + log.debug("successfully processed, id {}", fixedIncomeCashFlow.getId()); + + return null; + } } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java index 27fc8ce30..18214b4a2 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java @@ -16,6 +16,7 @@ import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeCashFlow; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowUpdateRequest; import ru.spcex.clearing.securities.config.ErrorResolverConfig; import ru.spcex.clearing.securities.config.ImdgTestConfig; import ru.spcex.clearing.securities.config.KafkaTestConfig; @@ -110,4 +111,43 @@ class FixedIncomeCashFlowServiceTest { FIXED_INCOME_CASH_FLOW_MATCHER.assertMatch(resultNew, predictableFixedIncomeCashFlow); } + @Test + void fixedIncomeCashFlowUpdateTest() throws InterruptedException { + //ARRANGE + FixedIncomeCashFlow existFixedIncomeCashFlow = new FixedIncomeCashFlow(); + existFixedIncomeCashFlow.setSecurityId(SECURITY_SYMBOL_LONG); + existFixedIncomeCashFlow.setNominalValue(BigDecimal.ZERO); + existFixedIncomeCashFlow.setAccruedCoupon(BigDecimal.ZERO); + existFixedIncomeCashFlow.setNumber(0L); + existFixedIncomeCashFlow.setValueDate(LocalDate.now().plusDays(7)); + Long id = fixedIncomeCashFlowImdg.insert(existFixedIncomeCashFlow); + + FixedIncomeCashFlowUpdateRequest updateRequest = new FixedIncomeCashFlowUpdateRequest(); + updateRequest.setId(id); + updateRequest.setSecuritySymbol(SECURITY_SYMBOL_STR); + updateRequest.setNominalValue(TEST_BIG_DECIMAL); + updateRequest.setAccruedCoupon(TEST_BIG_DECIMAL); + updateRequest.setNumber(TEST_LONG); + updateRequest.setValueDate(TEST_DATE); + + FixedIncomeCashFlow predictableFixedIncomeCashFlow = new FixedIncomeCashFlow(); + predictableFixedIncomeCashFlow.setSecurityId(SECURITY_SYMBOL_LONG); + predictableFixedIncomeCashFlow.setNominalValue(TEST_BIG_DECIMAL); + predictableFixedIncomeCashFlow.setAccruedCoupon(TEST_BIG_DECIMAL); + predictableFixedIncomeCashFlow.setNumber(TEST_LONG); + predictableFixedIncomeCashFlow.setValueDate(TEST_DATE); + + //ACT + String jsonString = getJsonStringForUPDATE(updateRequest, id); + + addRecordToKafka((MockConsumer) fixedIncomeCashFlowService.getConsumer(), TOPIC_FIXED_INCOME_CASH_FLOW_UPDATE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(id, mockProducer, producerRecord); + FixedIncomeCashFlow resultUpdate = fixedIncomeCashFlowImdg.getSingleObjectBySQL(String.format("securityId = %s", SECURITY_SYMBOL_STR)); + predictableFixedIncomeCashFlow.setId(id); + FIXED_INCOME_CASH_FLOW_MATCHER.assertMatch(resultUpdate, predictableFixedIncomeCashFlow); + } + + } \ No newline at end of file diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java index e5d1c2d50..50d6f0c8c 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java @@ -2,7 +2,10 @@ package ru.spcex.clearing.platform.messaging.domain.cud.securitites; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; import ru.spcex.platform.classes.base.interfaces.WithSecuritySymbol; import java.math.BigDecimal; @@ -27,6 +30,8 @@ public class FixedIncomeCashFlowUpdateRequest implements WithSecuritySymbol { public Long number; @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate valueDate; From de137377bc8954d110f193a41ddfb978e84bde49 Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 12:01:41 +0300 Subject: [PATCH 64/90] ClearingMemberCategoryServiceTest fix --- .../ClearingMemberCategoryServiceTest.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java index 4d78b455d..b864b48a7 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java @@ -105,7 +105,6 @@ class ClearingMemberCategoryServiceTest { memberCategoryNewRequest.setCompanyId(TEST_COMPANY.getId()); ClearingMemberCategory predictableClearingMemberCategory = new ClearingMemberCategory(); - predictableClearingMemberCategory.setId(ID); predictableClearingMemberCategory.setCompanyId(COMPANY_ID); predictableClearingMemberCategory.setClearingMemberCategory(clearingMemberCategory); @@ -117,6 +116,7 @@ class ClearingMemberCategoryServiceTest { //ASSERT waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); ClearingMemberCategory resultNew = memberCategoryImdg.getSingleObjectBySQL(String.format("clearingMemberCategory = %s", clearingMemberCategory)); + predictableClearingMemberCategory.setId(resultNew.getId()); MEMBER_CATEGORY_MATCHER.assertMatch(resultNew, predictableClearingMemberCategory); } @@ -132,28 +132,27 @@ class ClearingMemberCategoryServiceTest { //ARRANGE String clearingMemberCategory = CLEARING_CATEGORY_DICT_CODE; ClearingMemberCategory existsClearingMemberCategory = new ClearingMemberCategory(); - existsClearingMemberCategory.setId(ID); existsClearingMemberCategory.setClearingMemberCategory("0000"); existsClearingMemberCategory.setCompanyId(COMPANY_ID); - memberCategoryImdg.insert(existsClearingMemberCategory); + Long id = memberCategoryImdg.insert(existsClearingMemberCategory); ClearingMemberCategoryUpdateRequest memberCategoryUpdateRequest = new ClearingMemberCategoryUpdateRequest(); - memberCategoryUpdateRequest.setId(ID); + memberCategoryUpdateRequest.setId(id); memberCategoryUpdateRequest.setClearingMemberCategory(clearingMemberCategory); ClearingMemberCategory predictableClearingMemberCategory = new ClearingMemberCategory(); predictableClearingMemberCategory.setCompanyId(COMPANY_ID); - predictableClearingMemberCategory.setId(ID); + predictableClearingMemberCategory.setId(id); predictableClearingMemberCategory.setClearingMemberCategory(clearingMemberCategory); //ACT - String jsonString = getJsonStringForUPDATE(memberCategoryUpdateRequest, ID); + String jsonString = getJsonStringForUPDATE(memberCategoryUpdateRequest, id); addRecordToKafka((MockConsumer) clearingMemberCategoryService.getConsumer(), TOPIC_MEMBER_CATEGORY_UPDATE, PARTITION, 0, jsonString); //ASSERT - waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + waitingWhenAddedRecordAndCheckIt(id, mockProducer, producerRecord); - ClearingMemberCategory resultUpdating = memberCategoryImdg.getSingleObjectBySQL(String.format("clearingMemberCategory = %s", clearingMemberCategory)); + ClearingMemberCategory resultUpdating = memberCategoryImdg.getSingleObjectByID(id); MEMBER_CATEGORY_MATCHER.assertMatch(resultUpdating, predictableClearingMemberCategory); } @@ -168,19 +167,18 @@ class ClearingMemberCategoryServiceTest { //ARRANGE String clearingMemberCategory = "0000"; ClearingMemberCategory existsClearingMemberCategory = new ClearingMemberCategory(); - existsClearingMemberCategory.setId(ID); existsClearingMemberCategory.setClearingMemberCategory(clearingMemberCategory); - memberCategoryImdg.insert(existsClearingMemberCategory); + Long id = memberCategoryImdg.insert(existsClearingMemberCategory); CommonDeleteRequest memberCategoryDeleteRequest = new CommonDeleteRequest(); - memberCategoryDeleteRequest.setId(ID); + memberCategoryDeleteRequest.setId(id); //ACT - String jsonString = getJsonStringForDELETE(memberCategoryDeleteRequest, ID); + String jsonString = getJsonStringForDELETE(memberCategoryDeleteRequest, id); addRecordToKafka((MockConsumer) clearingMemberCategoryService.getConsumer(), TOPIC_MEMBER_CATEGORY_DELETE, PARTITION, 0, jsonString); //ASSERT - waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + waitingWhenAddedRecordAndCheckIt(id, mockProducer, producerRecord); ClearingMemberCategory resultDeleting = memberCategoryImdg.getSingleObjectBySQL(String.format("clearingMemberCategory = %s", clearingMemberCategory)); Assertions.assertNull(resultDeleting); From 0f3ef112a42ae2ea59aef017122f52e592a4dd3f Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 12:05:46 +0300 Subject: [PATCH 65/90] rename clearing-utils -> clearing-validation --- .../pom.xml | 4 +- .../ru/spcex/clearing/util/package-info.java | 6 +- .../exchangers/BiDirectionQueueExchanger.java | 132 +++++++++--------- .../validation/common/ValidationHelper.java | 0 .../common/rules/DateNotBeforeRule.java | 0 .../common/rules/DictionaryPresentRule.java | 0 .../common/rules/EndDtAfterStartDtRule.java | 0 .../common/rules/EnumPresentRule.java | 0 .../common/rules/FieldRequiredRule.java | 0 .../common/rules/IdPresentRule.java | 0 .../common/rules/IsLongValueRule.java | 0 .../common/rules/TimeNotBeforeRule.java | 0 clearing-parent/company-service/pom.xml | 2 +- clearing-parent/pom.xml | 2 +- clearing-parent/securities-service/pom.xml | 2 +- pom.xml | 2 +- 16 files changed, 75 insertions(+), 75 deletions(-) rename clearing-parent/{clearing-utils => clearing-validation}/pom.xml (95%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/util/package-info.java (97%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java (97%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java (100%) rename clearing-parent/{clearing-utils => clearing-validation}/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java (100%) diff --git a/clearing-parent/clearing-utils/pom.xml b/clearing-parent/clearing-validation/pom.xml similarity index 95% rename from clearing-parent/clearing-utils/pom.xml rename to clearing-parent/clearing-validation/pom.xml index 580382cc7..60ad3b00b 100644 --- a/clearing-parent/clearing-utils/pom.xml +++ b/clearing-parent/clearing-validation/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - clearing-utils - clearing-utils + clearing-validation + clearing-validation Clearing-module, dependency version of platform-utils jar SPCEX-1.0.0.0 diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/package-info.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/package-info.java similarity index 97% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/package-info.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/package-info.java index 636322526..4077b07c4 100644 --- a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/package-info.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/package-info.java @@ -1,4 +1,4 @@ -/** - * Утилиты с зависимостями от множества модулей clearing-* - */ +/** + * Утилиты с зависимостями от множества модулей clearing-* + */ package ru.spcex.clearing.util; \ No newline at end of file diff --git a/clearing-parent/clearing-utils/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 similarity index 97% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java index 0f08fe624..f8aef7bf6 100644 --- a/clearing-parent/clearing-utils/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,66 +1,66 @@ -package ru.spcex.clearing.util.services.exchangers; - -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.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import ru.spcex.clearing.platform.messaging.domain.BaseRequest; -import ru.spcex.clearing.platform.messaging.service.QueueConsumer; - -/** - * Синхронный обмен сообщениями с ассинхронным сервисом. - * Метод exchange() отправляет сообщение в очередь и дожидается ответа из другой очереди - */ -public class BiDirectionQueueExchanger> extends QueueConsumer implements InitializingBean, DisposableBean { - 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; - - /** - * Синхронно-ассинхронный обмен сообщениями - * - * @param kafkaQueue - * @param kafkaProducer - * @param outQueue отправляет в очередь - * @param inQueue слушает очередь, ожидает ответов - * @param listenClass типы объектов из inQueue - * @param timeout - максимальное ожидание ответа, в миллисекундах, 0 - неограничено - */ - public BiDirectionQueueExchanger(Consumer kafkaQueue, Producer kafkaProducer, - String outQueue, - String inQueue, Class listenClass, - long timeout) { - super(kafkaQueue, kafkaProducer); - this.outQueue = outQueue; - this.inQueue = inQueue; - this.listenClass = listenClass; - this.timeout = timeout; - } - - /** - * Отправить сообщение message в outQueue и дождаться ответа из очереди inQueue - * - * @param message - * @return - * @throws InterruptedException - */ - public TOut exchange(TIn message) throws InterruptedException { - //todo impl BiDirectionQueueExchanger - return null; - } - - @Override - public void destroy() throws Exception { - log.debug("Listener {} for async exchange {}-{} close", this, outQueue, inQueue); - } - - @Override - public void afterPropertiesSet() throws Exception { - log.debug("Listener {} for async exchange {}-{} ready", this, outQueue, inQueue); - } -} +package ru.spcex.clearing.util.services.exchangers; + +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.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; + +/** + * Синхронный обмен сообщениями с ассинхронным сервисом. + * Метод exchange() отправляет сообщение в очередь и дожидается ответа из другой очереди + */ +public class BiDirectionQueueExchanger> extends QueueConsumer implements InitializingBean, DisposableBean { + 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; + + /** + * Синхронно-ассинхронный обмен сообщениями + * + * @param kafkaQueue + * @param kafkaProducer + * @param outQueue отправляет в очередь + * @param inQueue слушает очередь, ожидает ответов + * @param listenClass типы объектов из inQueue + * @param timeout - максимальное ожидание ответа, в миллисекундах, 0 - неограничено + */ + public BiDirectionQueueExchanger(Consumer kafkaQueue, Producer kafkaProducer, + String outQueue, + String inQueue, Class listenClass, + long timeout) { + super(kafkaQueue, kafkaProducer); + this.outQueue = outQueue; + this.inQueue = inQueue; + this.listenClass = listenClass; + this.timeout = timeout; + } + + /** + * Отправить сообщение message в outQueue и дождаться ответа из очереди inQueue + * + * @param message + * @return + * @throws InterruptedException + */ + public TOut exchange(TIn message) throws InterruptedException { + //todo impl BiDirectionQueueExchanger + return null; + } + + @Override + public void destroy() throws Exception { + log.debug("Listener {} for async exchange {}-{} close", this, outQueue, inQueue); + } + + @Override + public void afterPropertiesSet() throws Exception { + log.debug("Listener {} for async exchange {}-{} ready", this, outQueue, inQueue); + } +} diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/IsLongValueRule.java diff --git a/clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java similarity index 100% rename from clearing-parent/clearing-utils/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java diff --git a/clearing-parent/company-service/pom.xml b/clearing-parent/company-service/pom.xml index 9913e8df4..ee17025df 100644 --- a/clearing-parent/company-service/pom.xml +++ b/clearing-parent/company-service/pom.xml @@ -38,7 +38,7 @@ ru.spcex.clearing - clearing-utils + clearing-validation org.springframework.boot diff --git a/clearing-parent/pom.xml b/clearing-parent/pom.xml index e71a79d1a..7f495921e 100644 --- a/clearing-parent/pom.xml +++ b/clearing-parent/pom.xml @@ -21,7 +21,7 @@ backend-api imdg security-util - clearing-utils + clearing-validation db-scripts dbf-importer dbf-exporter diff --git a/clearing-parent/securities-service/pom.xml b/clearing-parent/securities-service/pom.xml index 63e85f10a..ae27be76c 100644 --- a/clearing-parent/securities-service/pom.xml +++ b/clearing-parent/securities-service/pom.xml @@ -26,7 +26,7 @@ ru.spcex.clearing - clearing-utils + clearing-validation ru.spcex.platform diff --git a/pom.xml b/pom.xml index 6d9c0427c..b5e15a784 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,7 @@ ru.spcex.clearing - clearing-utils + clearing-validation ${global.project.version} From 8288b4c988e9d617bd56e82310f8408104741e4a Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 6 Apr 2023 12:44:56 +0300 Subject: [PATCH 66/90] =?UTF-8?q?company-service:=20CompanyRoleSetService?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=8E?= =?UTF-8?q?=D0=BD=D0=B8=D1=82=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/CompanyValidationConfig.java | 8 ++ .../config/validation/ValidationConfig.java | 5 +- .../service/CompanyInfoServiceTest.java | 78 ++++++++++++------- .../company/service/CompanyServiceTest.java | 3 + .../adapter/ImdgTransactionalHazelcast.java | 9 +++ 5 files changed, 72 insertions(+), 31 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java index 00c928cd5..6e90cdbee 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java @@ -120,6 +120,14 @@ public class CompanyValidationConfig { context.setValidatedObject(companyDeleteRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); + addImdg.accept(IMDGDistributedNames.Map_CorporationSoleTypeDictionary); + addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary); + addImdg.accept(IMDGDistributedNames.Map_AllowedDictionary); + addImdg.accept(IMDGDistributedNames.Map_LegalKindDictionary); + addImdg.accept(IMDGDistributedNames.Map_LegalKindDictionary); + addImdg.accept(IMDGDistributedNames.Map_OrganizationTypeDictionary); 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/config/validation/ValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java index 17f450e90..1a922efe6 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 @@ -34,14 +34,13 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_ContactTypeDictionary, ContactTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_Contact, Contact.class); - addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, DocumentTypeDictionary.class); - addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CorporationSoleTypeDictionary, CorporationSoleTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_AllowedDictionary, AllowedDictionary.class); addImdg.accept(IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class); addImdg.accept(IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class); - addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); return imdg; 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 b420c42a6..dfebef889 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 @@ -14,13 +14,18 @@ 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.profile.CompanyInfo; +import ru.clearing.platform.dictionary.*; +import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; 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.company.CompanyInfoUpdateRequest; +import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @@ -32,6 +37,15 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanyInfoService.class, + + CompanyService.class, + CompanyValidationConfig.class, + ValidationConfig.class, + CompanySymbolService.class, + AccountNotificationHelper.class, + RelationHelper.class, + BeanConfiguration.class, + KafkaConfigTest.class, HazelcastServiceTestConfiguration.class}) class CompanyInfoServiceTest { @@ -57,16 +71,23 @@ class CompanyInfoServiceTest { hazelcastServiceTest.waitAvailable(); companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); - /* todo залить тестовые словари: - IMDGDistributedNames.Map_WorkflowStatusDictionary, DocumentTypeDictionary.class); -IMDGDistributedNames.Map_CompanySymbolDictionary, DocumentTypeDictionary.class); -IMDGDistributedNames.Map_CorporationSoleTypeDictionary, CorporationSoleTypeDictionary.class); -IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); -IMDGDistributedNames.Map_AllowedDictionary, AllowedDictionary.class); -IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class); -IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class); -IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.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"); + + } + + 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); } /** @@ -74,13 +95,13 @@ IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); * Тест проверяет обновление сущности {@link CompanyInfo} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@link CompanyInfoUpdateRequest}:
* {@link CompanyInfoUpdateRequest#id} - Идентификатор записи
- * {@link CompanyInfoUpdateRequest#corporationSoleType} - 1234
- * {@link CompanyInfoUpdateRequest#countryCode} - 1234
+ * {@link CompanyInfoUpdateRequest#corporationSoleType} - GDIR
+ * {@link CompanyInfoUpdateRequest#countryCode} - RUS
* {@link CompanyInfoUpdateRequest#description} - updated description
- * {@link CompanyInfoUpdateRequest#professionalSign} - 1234
- * {@link CompanyInfoUpdateRequest#legalKind} - 1234
- * {@link CompanyInfoUpdateRequest#organizationType} - 1234
- * {@link CompanyInfoUpdateRequest#residence} - 1234
+ * {@link CompanyInfoUpdateRequest#professionalSign} - ALWD
+ * {@link CompanyInfoUpdateRequest#legalKind} - JURD
+ * {@link CompanyInfoUpdateRequest#organizationType} - NCRD
+ * {@link CompanyInfoUpdateRequest#residence} - RUS
* {@link CompanyInfoUpdateRequest#shortNameEng} - updated shortNameEng
* {@link CompanyInfoUpdateRequest#fullNameEng} - updated fullNameEng
* {@link CompanyInfoUpdateRequest#shortName} - updated shortName
@@ -105,18 +126,19 @@ IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); existsCompanyInfo.setFullName("exists fullName"); Company existsCompany = new Company(); existsCompany.setId(ID); + existsCompany.setWorkflowStatus(WorkflowStatus.Active.getKey()); existsCompany.setProfile(existsCompanyInfo); companyImdg.insert(existsCompany); CompanyInfoUpdateRequest companyInfoUpdateRequest = new CompanyInfoUpdateRequest(); companyInfoUpdateRequest.setId(ID); - companyInfoUpdateRequest.setCorporationSoleType("1234"); - companyInfoUpdateRequest.setCountryCode("1234"); + companyInfoUpdateRequest.setCorporationSoleType("GDIR"); + companyInfoUpdateRequest.setCountryCode("RUS"); companyInfoUpdateRequest.setDescription("updated description"); - companyInfoUpdateRequest.setProfessionalSign("1234"); - companyInfoUpdateRequest.setLegalKind("1234"); - companyInfoUpdateRequest.setOrganizationType("1234"); - companyInfoUpdateRequest.setResidence("1234"); + companyInfoUpdateRequest.setProfessionalSign("ALWD"); + companyInfoUpdateRequest.setLegalKind("JURD"); + companyInfoUpdateRequest.setOrganizationType("NCRD"); + companyInfoUpdateRequest.setResidence("RUS"); companyInfoUpdateRequest.setShortNameEng("updated shortNameEng"); companyInfoUpdateRequest.setFullNameEng("updated fullNameEng"); companyInfoUpdateRequest.setShortName("updated shortName"); @@ -125,13 +147,13 @@ IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); CompanyInfo predictableCompanyInfo = new CompanyInfo(); predictableCompanyInfo.setId(ID); predictableCompanyInfo.setCompanyId(ID); - predictableCompanyInfo.setCorporationSoleType("1234"); - predictableCompanyInfo.setCountryCode("1234"); + predictableCompanyInfo.setCorporationSoleType("GDIR"); + predictableCompanyInfo.setCountryCode("RUS"); predictableCompanyInfo.setDescription("updated description"); - predictableCompanyInfo.setProfessionalSign("1234"); - predictableCompanyInfo.setLegalKind("1234"); - predictableCompanyInfo.setOrganizationType("1234"); - predictableCompanyInfo.setResidence("1234"); + predictableCompanyInfo.setProfessionalSign("ALWD"); + predictableCompanyInfo.setLegalKind("JURD"); + predictableCompanyInfo.setOrganizationType("NCRD"); + predictableCompanyInfo.setResidence("RUS"); predictableCompanyInfo.setShortNameEng("updated shortNameEng"); predictableCompanyInfo.setFullNameEng("updated fullNameEng"); predictableCompanyInfo.setShortName("updated shortName"); 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 e2519cd26..bdcf902a6 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 @@ -45,6 +45,9 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; CompanyService.class, CompanyValidationConfig.class, ValidationConfig.class, + CompanySymbolService.class, + AccountNotificationHelper.class, + RelationHelper.class, KafkaConfigTest.class, HazelcastServiceTestConfiguration.class, diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java index 8a241c6af..58fa644e8 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionalHazelcast.java @@ -6,6 +6,7 @@ import com.hazelcast.core.IdGenerator; import com.hazelcast.core.TransactionalMap; import com.hazelcast.query.Predicate; import com.hazelcast.query.Predicates; +import com.hazelcast.query.SqlPredicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -90,6 +91,14 @@ public class ImdgTransactionalHazelcast implements Im } } + @Override + public Collection getCollectionObjectsBySQL(String paramString) { + SqlPredicate sqlPredicate = new SqlPredicate(paramString); + Collection found = map.values(sqlPredicate); + List result = new ArrayList<>(found); // Hazelcast может вернуть proxy-коллекцию + return result; + } + /** * возвращает коллекцию объектов, удовлетворяющий условиям на поля */ From 34d1a8c4443f90655235eade6cb3cf1d37401492 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 6 Apr 2023 13:52:29 +0300 Subject: [PATCH 67/90] company-service fix log error in test --- .../company/service/ClearingMemberCategoryServiceTest.java | 5 +++++ .../clearing/company/service/CompanyInfoServiceTest.java | 5 +++++ .../spcex/clearing/company/service/CompanyServiceTest.java | 6 ++++++ .../clearing/company/service/CompanySymbolServiceTest.java | 6 ++++++ .../spcex/clearing/company/service/ContactServiceTest.java | 6 ++++++ .../company/service/ProfileDocumentServiceTest.java | 6 +++++- 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java index b864b48a7..df802532f 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java @@ -22,6 +22,7 @@ import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.ClearingMemberCategoryValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory.Matcher; +import ru.spcex.clearing.company.utils.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -35,6 +36,8 @@ import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import javax.annotation.PostConstruct; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration.currentID; import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.company.utils.TestUtils.*; @@ -94,6 +97,8 @@ class ClearingMemberCategoryServiceTest { clearingCategoryDictionary.setCode(CLEARING_CATEGORY_DICT_CODE); clearingCategoryDictionaryImdg.insert(clearingCategoryDictionary); + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } @Test 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 dfebef889..8ab19f2f4 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 @@ -21,6 +21,7 @@ import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.spcex.clearing.company.utils.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -31,6 +32,8 @@ import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import javax.annotation.PostConstruct; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.company.utils.TestUtils.*; @@ -80,6 +83,8 @@ class CompanyInfoServiceTest { putToDictionary(IMDGDistributedNames.Map_LegalKindDictionary, new LegalKindDictionary(), "JURD"); putToDictionary(IMDGDistributedNames.Map_OrganizationTypeDictionary, new OrganizationTypeDictionary(), "NCRD"); + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } private void putToDictionary(String mapName, D object, String code) { 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 bdcf902a6..eacb5cd11 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 @@ -23,6 +23,7 @@ import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.spcex.clearing.company.utils.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -37,6 +38,8 @@ import javax.annotation.PostConstruct; import java.util.Map; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.company.utils.TestUtils.*; @@ -97,6 +100,9 @@ class CompanyServiceTest { cSymbol.setShortname(" CLRC key"); companySymbolDictionaryImdg.insert(cSymbol); } + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } /** 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 456b4a893..7ddfaaaee 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 @@ -16,6 +16,7 @@ import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.spcex.clearing.company.utils.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -25,6 +26,8 @@ import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import javax.annotation.PostConstruct; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.company.utils.TestUtils.*; @@ -56,6 +59,9 @@ class CompanySymbolServiceTest { private void init() { hazelcastServiceTest.waitAvailable(); companySymbolsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } /** diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java index e361852d5..5864d1538 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java @@ -21,6 +21,7 @@ import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.ContactValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.spcex.clearing.company.utils.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -33,6 +34,8 @@ import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import javax.annotation.PostConstruct; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.company.utils.TestUtils.*; @@ -85,6 +88,9 @@ class ContactServiceTest { IMDGDistributedNames.Map_ContactTypeDictionary, ContactTypeDictionary.class ); contactTypeDictionaryImdg.insert(contactTypeDictionary); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } @Test void contactNew() throws InterruptedException { diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java index 298d1483d..3042b85f5 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java @@ -21,6 +21,7 @@ import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.ProfileDocumentValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.spcex.clearing.company.utils.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -35,6 +36,8 @@ import javax.annotation.PostConstruct; import java.time.LocalDate; import java.time.temporal.ChronoUnit; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration.currentID; import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.company.utils.TestUtils.*; @@ -104,7 +107,8 @@ class ProfileDocumentServiceTest { documentTypeDictionary1.setName("new_test_name"); documentTypeDictionaryImdg.insert(documentTypeDictionary1); - + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } /** From 0b1dc8f98d578f96ce7637b2cf425a6a4126c1d4 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 6 Apr 2023 14:38:48 +0300 Subject: [PATCH 68/90] . --- .../java/ru/spcex/clearing/error/ClearingErrorInternal.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java index 559837733..f7052004c 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/error/ClearingErrorInternal.java @@ -4,8 +4,8 @@ import ru.spcex.platform.utils.enumeration.IErrorEnumId; public enum ClearingErrorInternal implements IErrorEnumId { ClearingNotAllowed(1L), - AccountNotActive(2L), - CompanyNotActive(3L), + AccountNotActive(5415L), + CompanyNotActive(5411L), FinancialObligationNotSatisfied(4L), ; private final Long id; From c4b3c918c3e6a928bba629099381046e1e56ccc7 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 6 Apr 2023 17:56:17 +0300 Subject: [PATCH 69/90] =?UTF-8?q?company-service=20=D0=BF=D0=BE=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D1=83=20=D1=81=20hazelcast=20(=D0=B5=D0=B3=D0=BE=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=D0=BE=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20-=20=D1=81=D0=BB=D0=B8=D1=88=D0=BA=D0=BE=D0=BC=20?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=80=D0=B0=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=81=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=BC=20=D0=B2?= =?UTF-8?q?=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=B8?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../company/service/CompanyService.java | 22 +++++-------------- .../company/service/CompanyServiceTest.java | 13 +++++++++-- .../ImdgTransactionProviderHazelcast.java | 6 +++++ .../service/HazelcastServiceBase.java | 21 ++++++++---------- 4 files changed, 32 insertions(+), 30 deletions(-) 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 798e4c72f..98ac9eb3b 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 @@ -10,7 +10,6 @@ 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.CompanySymbols; -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.imdg.IMDGDistributedNames; @@ -32,21 +31,17 @@ 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.Map; import java.util.Objects; import java.util.function.Function; -// todo добавить транзакции! Это важно из-за AccountNotification @Service public class CompanyService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final RequestHelper requestHelper; private final ImdgProvider imdgProvider; - // private final Imdg companyMap; - private final Imdg companySymnbolsMap; - // private final Imdg relationMap; + private final Imdg companySymbolsMap; private final ImdgId idSequence; protected UserRoleVerification userRoleVerification; protected IMessageResolver messageResolver; @@ -81,11 +76,8 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.imdgProvider = imdgProvider; this.messageResolver = messageResolver; this.requestHelper = new RequestHelper(log, messageResolver); -// this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); -// this.relationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); - - this.companySymnbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); this.userRoleVerification = userRoleVerification; this.validationHelper = validationHelper; @@ -213,6 +205,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { } else { log.trace("Null new WorkflowStatus"); } + companyMap.update(company); txOk = true; } finally { if (txOk) @@ -269,7 +262,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { company.setUpdated(Instant.now()); - CompanySymbols companySymbol = companySymnbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); + CompanySymbols companySymbol = companySymbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); if (companySymbol == null) { log.warn("CompanySymbols not found for companyId={}", company.getId()); } else { @@ -279,10 +272,10 @@ public class CompanyService extends QueueConsumer implements InitializingBean { String prevStatus = company.getWorkflowStatus(); company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - log.debug("Update company.id={}", company.getId()); - companyMap.update(company); relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + log.debug("Update company.id={}", company.getId()); + companyMap.update(company); txOk = true; } finally { @@ -292,9 +285,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { transaction.rollbackTransaction(); } return null; - -// Company company = companyMap.getSingleObjectByID(req.getId()); -// companyMap.delete(company); } } 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 eacb5cd11..2112c5b8d 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 @@ -130,9 +130,18 @@ class CompanyServiceTest { //ASSERT waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); - Company resultDeleting = companyImdg.getSingleObjectByID(ID); + //Company resultDeleting = companyImdg.getSingleObjectByID(ID); + Company resultDeleting = companyImdg.getSingleObjectBySQL("id=" + ID); Assertions.assertEquals(WorkflowStatus.Blocked.getKey(), resultDeleting.getWorkflowStatus()); - //Assertions.assertNull(resultDeleting); + + { + // 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!"); + } + } } diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java index f36ccea77..34e9ea3b1 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgTransactionProviderHazelcast.java @@ -11,9 +11,12 @@ import ru.spcex.platform.imdg.api.ImdgTransaction; public class ImdgTransactionProviderHazelcast implements ImdgTransaction { private TransactionContext ctx; private HazelcastInstance hz; + private boolean txStatus; @Override public Imdg getImdg(String key, Class clazz) { + if (!txStatus) + throw new IllegalStateException("Transaction was not open"); ImdgTransactionalHazelcast imdg = new ImdgTransactionalHazelcast<>(); imdg.setMap(ctx.getMap(key)); imdg.setHzInstance(hz); @@ -35,16 +38,19 @@ public class ImdgTransactionProviderHazelcast implements ImdgTransaction { @Override public void commitTransaction() { this.ctx.commitTransaction(); + txStatus = false; } @Override public void beginTransaction() { this.ctx.beginTransaction(); + txStatus = true; } @Override public void rollbackTransaction() { this.ctx.rollbackTransaction(); + txStatus = false; } public TransactionContext getCtx() { diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java index c515841f7..0fb7b039f 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/service/HazelcastServiceBase.java @@ -268,21 +268,18 @@ public abstract class HazelcastServiceBase } } + /** + * Переподключение во время транзакции не предусмотрено. + * Транзакция - объект с коротким жизненным циклом. + * @return + */ @Override public ImdgTransaction newTransaction() { ImdgTransactionProviderHazelcast transactionalContext = new ImdgTransactionProviderHazelcast(); - statusSubscribe(new IHazelcastClusterStatus() { - @Override - public void getAvailable(HazelcastInstance hazelcastNotInited) { - transactionalContext.setHz(hazelcastInstance); - transactionalContext.setCtx(hazelcastNotInited.newTransactionContext( - new TransactionOptions().setTransactionType(TransactionOptions.TransactionType.TWO_PHASE) - )); - } - @Override - public void getUnavailable(HazelcastInstance hazelcastNotInited) { - } - }); + transactionalContext.setHz(hazelcastInstance); + transactionalContext.setCtx(hazelcastInstance.newTransactionContext( + new TransactionOptions().setTransactionType(TransactionOptions.TransactionType.TWO_PHASE) + )); return transactionalContext; } From cf22ea1074d88cd57bffd5534ec7e5848c63a2b9 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 6 Apr 2023 17:59:47 +0300 Subject: [PATCH 70/90] platform-imdg-api-hazelcast-impl: HazelcastHelper refactoring --- .../account/config/HazelcastServiceTestConfiguration.java | 2 +- .../controller/config/HazelcastServiceTestConfiguration.java | 2 +- .../java/ru/spcex/clearing/balance/config/ImdgTestConfig.java | 2 +- .../clearing/config/HazelcastServiceTestConfiguration.java | 2 +- .../company/config/HazelcastServiceTestConfiguration.java | 2 +- .../imdg/services/AbstractHazelcastLifecycleSupport.java | 2 +- .../registry/config/HazelcastServiceTestConfiguration.java | 2 +- .../scheduler/config/HazelcastServiceTestConfiguration.java | 2 +- .../ru/spcex/clearing/securities/config/ImdgTestConfig.java | 2 +- .../utility/config/HazelcastServiceTestConfiguration.java | 2 +- .../spcex/platform/imdg/iml/hazelcast/util/HazelcastHelper.java | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/config/HazelcastServiceTestConfiguration.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/config/HazelcastServiceTestConfiguration.java index 7ee4bc8fa..323c2e34e 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/config/HazelcastServiceTestConfiguration.java @@ -43,7 +43,7 @@ public class HazelcastServiceTestConfiguration { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/HazelcastServiceTestConfiguration.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/HazelcastServiceTestConfiguration.java index 21f476282..f6414f2a1 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/HazelcastServiceTestConfiguration.java @@ -41,7 +41,7 @@ public class HazelcastServiceTestConfiguration { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.newHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/ImdgTestConfig.java b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/ImdgTestConfig.java index c629b65d7..b1eaa9bc0 100644 --- a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/ImdgTestConfig.java +++ b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/ImdgTestConfig.java @@ -58,7 +58,7 @@ public class ImdgTestConfig { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/config/HazelcastServiceTestConfiguration.java b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/config/HazelcastServiceTestConfiguration.java index 6fa6dea43..6611b764d 100644 --- a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/config/HazelcastServiceTestConfiguration.java @@ -44,7 +44,7 @@ public class HazelcastServiceTestConfiguration { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java index fbff8eb0c..5605eaff9 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java @@ -44,7 +44,7 @@ public class HazelcastServiceTestConfiguration { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java index 8b26a9649..b715b032e 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/AbstractHazelcastLifecycleSupport.java @@ -115,7 +115,7 @@ public abstract class AbstractHazelcastLifecycleSupport implements InitializingB throw new RuntimeException("MapStore multithreaded not complete.", e); } - HazelcastHelper.otcSystem_setStorageState(true, hazelcastServerInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastServerInstance); loadTime = System.currentTimeMillis() - loadTime; log.info("All map load time {} ms", loadTime); diff --git a/clearing-parent/registry-service/src/test/java/ru/spcex/clearing/registry/config/HazelcastServiceTestConfiguration.java b/clearing-parent/registry-service/src/test/java/ru/spcex/clearing/registry/config/HazelcastServiceTestConfiguration.java index a517c8d42..ef4458f82 100644 --- a/clearing-parent/registry-service/src/test/java/ru/spcex/clearing/registry/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/registry-service/src/test/java/ru/spcex/clearing/registry/config/HazelcastServiceTestConfiguration.java @@ -44,7 +44,7 @@ public class HazelcastServiceTestConfiguration { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/config/HazelcastServiceTestConfiguration.java b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/config/HazelcastServiceTestConfiguration.java index 48b9644d4..ed08bbbb9 100644 --- a/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/scheduler-service/src/test/java/ru/specx/clearing/scheduler/config/HazelcastServiceTestConfiguration.java @@ -43,7 +43,7 @@ public class HazelcastServiceTestConfiguration { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.newHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java index 839542afd..9fa010b83 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java @@ -60,7 +60,7 @@ public class ImdgTestConfig { networkConfig.setJoin(joinConfig); cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/clearing-parent/utility-service/src/test/java/ru/spcex/clearing/utility/config/HazelcastServiceTestConfiguration.java b/clearing-parent/utility-service/src/test/java/ru/spcex/clearing/utility/config/HazelcastServiceTestConfiguration.java index d1cfc84d0..6ec937bd0 100644 --- a/clearing-parent/utility-service/src/test/java/ru/spcex/clearing/utility/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/utility-service/src/test/java/ru/spcex/clearing/utility/config/HazelcastServiceTestConfiguration.java @@ -44,7 +44,7 @@ public class HazelcastServiceTestConfiguration { cfg.setNetworkConfig(networkConfig); hazelcastInstance = Hazelcast.newHazelcastInstance(cfg); - HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance); + HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); } diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/util/HazelcastHelper.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/util/HazelcastHelper.java index 5898d2a40..605849f15 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/util/HazelcastHelper.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/util/HazelcastHelper.java @@ -123,7 +123,7 @@ public final class HazelcastHelper { return Boolean.valueOf(systemMap.get(STATE_OF_IMDG_SERVER)); } - public static void otcSystem_setStorageState(boolean val, HazelcastInstance hazelcast) { + public static void imdgSystem_setStorageState(boolean val, HazelcastInstance hazelcast) { IMap systemMap = hazelcast.getMap(CLEARING_SYSTEM_MAP); systemMap.set(STATE_OF_IMDG_SERVER, Boolean.toString(val)); } From 466037cd227257844a4f856fdf81609b44539f7a Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 18:19:46 +0300 Subject: [PATCH 71/90] DictionaryPresentRule add additional checks --- .../common/rules/DictionaryPresentRule.java | 51 +++++++++++-------- .../common/rules/FieldRequiredRule.java | 19 ++++--- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java index 9cae88bc0..3e4cee495 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -15,6 +15,7 @@ import java.util.function.Function; /** * Проверка поля с кодом из словаря (таблицы *_dictionary) + * * @param Класс проверяемого объекта * @param Класс словаря */ @@ -24,58 +25,68 @@ public record DictionaryPresentRule(String fiel Class dictionaryClass, IErrorEnumId errorEmptyRequiredValue, IErrorEnumId errorWrongDictionaryValue, - boolean required) implements IValidationRule> { + boolean required, + Function[] additionalChecks) implements IValidationRule> { + /** - * @param fieldName Название поля - * @param getter Метод получения проверяемого значения - * @param dictionaryName Название словаря (см. IMDGDistributedNames) - * @param dictionaryClass Класс словаря (классы *Dictionary.class) - * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param dictionaryName Название словаря (см. IMDGDistributedNames) + * @param dictionaryClass Класс словаря (классы *Dictionary.class) + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое * @param errorWrongDictionaryValue Ошибка, которая будет возвращена, если поле не найдено в словаре - * @param required Флаг обязательности - * @param Класс проверяемого объекта - * @param Класс словаря + * @param required Флаг обязательности + * @param additionalChecks Дополнительные проверки, связанные с этим полем + * @param Класс проверяемого объекта + * @param Класс словаря */ + @SafeVarargs public static DictionaryPresentRule instance(String fieldName, Function getter, String dictionaryName, Class dictionaryClass, IErrorEnumId errorEmptyRequiredValue, IErrorEnumId errorWrongDictionaryValue, - boolean required) { + boolean required, + Function... additionalChecks) { return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, errorEmptyRequiredValue, errorWrongDictionaryValue, - required); + required, + additionalChecks); } /** - * @param fieldName Название поля - * @param getter Метод получения проверяемого значения - * @param dictionaryName Название словаря (см. IMDGDistributedNames) - * @param dictionaryClass Класс словаря (классы *Dictionary.class) - * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param dictionaryName Название словаря (см. IMDGDistributedNames) + * @param dictionaryClass Класс словаря (классы *Dictionary.class) + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое * @param errorWrongDictionaryValue Ошибка, которая будет возвращена, если поле не найдено в словаре - * @param Класс проверяемого объекта - * @param Класс словаря + * @param additionalChecks Дополнительные проверки, связанные с этим полем + * @param Класс проверяемого объекта + * @param Класс словаря */ + @SafeVarargs public static DictionaryPresentRule instance(String fieldName, Function getter, String dictionaryName, Class dictionaryClass, IErrorEnumId errorEmptyRequiredValue, - IErrorEnumId errorWrongDictionaryValue) { + IErrorEnumId errorWrongDictionaryValue, + Function... additionalChecks) { return new DictionaryPresentRule<>(fieldName, getter, dictionaryName, dictionaryClass, errorEmptyRequiredValue, errorWrongDictionaryValue, - true); + true, + additionalChecks); } @Override diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java index b9f5bb89c..eaa468190 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -11,9 +11,13 @@ import java.util.function.Function; /** * Проверка обязательности поля (not null) + * + * @param fieldName Название поля + * @param getter Метод получения значения * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое - * @param Класс проверяемого объекта - * @param Класс проверяемого значения + * @param additionalChecks Дополнительные проверки, связанные с этим полем + * @param Класс проверяемого объекта + * @param Класс проверяемого значения */ public record FieldRequiredRule( String fieldName, @@ -23,17 +27,18 @@ public record FieldRequiredRule( ) implements IValidationRule> { /** - * @param fieldName Название поля - * @param getter Метод получения значения + * @param fieldName Название поля + * @param getter Метод получения значения * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое - * @param Класс проверяемого объекта - * @param Класс проверяемого значения + * @param additionalChecks Дополнительные проверки, связанные с этим полем + * @param Класс проверяемого объекта + * @param Класс проверяемого значения */ @SafeVarargs public static FieldRequiredRule instance(String fieldName, Function getter, IErrorEnumId errorEmptyRequiredValue, - Function ... additionalChecks) { + Function... additionalChecks) { if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue"); return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue, additionalChecks); } From 1d173afccb60922be791e89149ce9d5ad7c4207a Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 18:24:58 +0300 Subject: [PATCH 72/90] DictionaryPresentRule add additional checks (fix) --- .../validation/common/rules/DictionaryPresentRule.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java index 3e4cee495..30c25318b 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -108,6 +108,11 @@ public record DictionaryPresentRule(String fiel if (dictionaryFromMap == null) { return of(errorWrongDictionaryValue, fieldName); } + for (Function additionalCheck : additionalChecks) { + IErrorEnumId validationError = additionalCheck.apply(dictionaryFromMap); + if (validationError != null) + return of(validationError, fieldName); + } return empty(); } From d7680f6bdfb55690176da5c15cc8783c84ac465e Mon Sep 17 00:00:00 2001 From: psemenkov Date: Thu, 6 Apr 2023 18:35:13 +0300 Subject: [PATCH 73/90] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=83=D1=82=D0=B8=D0=BB=D0=B8=D1=82=D1=8B=20=D0=B2=20=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=20test-clearing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/backend-api/pom.xml | 5 ++ .../Jackson2HttpConverterTestConfig.java | 31 +------- .../queue/AbstractControllerTest.java | 14 ++-- .../account/BankAccountControllerTest.java | 2 +- ...tClearingMemberCategoryControllerTest.java | 2 +- .../EditCompanyInfoControllerTest.java | 2 +- .../EditCompanySymbolControllerTest.java | 2 +- .../company/EditContactControllerTest.java | 2 +- .../queue/company/RelationControllerTest.java | 2 +- .../misc/NotificationControllerTest.java | 2 +- .../queue/misc/SessionControllerTest.java | 2 +- .../PaymentInstructionControllerTest.java | 2 +- .../scheduler/LauncherControllerTest.java | 4 +- .../PlannerAllTodayControllerTest.java | 2 +- .../scheduler/PlannerControllerTest.java | 2 +- .../queue/user/UserControllerTest.java | 2 +- .../utilities/StatementControllerTest.java | 2 +- .../backendapi/controller/utils/JsonUtil.java | 47 ----------- clearing-parent/pom.xml | 1 + clearing-parent/test-clearing/pom.xml | 77 +++++++++++++++++++ .../java/ru/spcex/clearing/imdg/JsonUtil.java | 73 ++++++++++++++++++ .../clearing/imdg/MatcherFactoryImdg.java} | 15 ++-- .../ru/spcex/clearing/imdg}/TestUtils.java | 2 +- pom.xml | 5 ++ 24 files changed, 194 insertions(+), 106 deletions(-) delete mode 100644 clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/JsonUtil.java create mode 100644 clearing-parent/test-clearing/pom.xml create mode 100644 clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/JsonUtil.java rename clearing-parent/{backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/MatcherFactory.java => test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryImdg.java} (84%) rename clearing-parent/{backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils => test-clearing/src/main/java/ru/spcex/clearing/imdg}/TestUtils.java (98%) diff --git a/clearing-parent/backend-api/pom.xml b/clearing-parent/backend-api/pom.xml index a07748ce8..ba7ad975c 100644 --- a/clearing-parent/backend-api/pom.xml +++ b/clearing-parent/backend-api/pom.xml @@ -67,6 +67,11 @@ spring-test test
+ + ru.spcex.clearing + test-clearing + test + org.skyscreamer jsonassert diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java index 8abb52f95..7cabe0661 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java @@ -1,40 +1,15 @@ package ru.spcex.clearing.backendapi.controller.config; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import ru.spcex.clearing.imdg.JsonUtil; @Configuration public class Jackson2HttpConverterTestConfig { @Bean("customJsonHttpConverter") public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { - return new MappingJackson2HttpMessageConverter(JacksonObjectMapper.getMapper()); - } - - public static class JacksonObjectMapper extends ObjectMapper { - private static final ObjectMapper MAPPER = new JacksonObjectMapper(); - - private JacksonObjectMapper() { - //настройки Ильи - configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); - //модуль для корректной сериализации LocalDateTime в поля JSON - JavaTimeModule модуль библиотеки jackson-datatype-jsr310 - registerModule(new JavaTimeModule()); - configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); - //запрещаем доступ ко всем полям и методам класса и потом разрешаем доступ только к полям, нужны чтобы не было лишних полей из-за методов как: public ActionType getActionType() у BankAccountNewAction - setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); - setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - //не сериализуем null-поля -// setSerializationInclusion(JsonInclude.Include.NON_NULL); - } - - public static ObjectMapper getMapper() { - return MAPPER; - } + return new MappingJackson2HttpMessageConverter(JsonUtil.JacksonObjectMapper.getMapper()); } } \ No newline at end of file diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java index d85555b9d..d210e7118 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java @@ -55,11 +55,11 @@ import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; import ru.spcex.clearing.backendapi.controller.response.cud.CudResponseTest; import ru.spcex.clearing.backendapi.controller.response.cud.QueueSuccessResponse; import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse; -import ru.spcex.clearing.backendapi.controller.utils.MatcherFactory; -import ru.spcex.clearing.backendapi.controller.utils.TestUtils; import ru.spcex.clearing.backendapi.domain.actions.IAction; import ru.spcex.clearing.backendapi.meta.GetResponseFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.imdg.MatcherFactoryImdg; +import ru.spcex.clearing.imdg.TestUtils; import ru.spcex.clearing.platform.messaging.domain.ActionType; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -80,9 +80,9 @@ import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.readValue; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; -import static ru.spcex.clearing.backendapi.controller.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.imdg.JsonUtil.readValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.MatcherFactoryImdg.usingIgnoringFieldsComparator; @ContextConfiguration(classes = { @@ -156,8 +156,8 @@ import static ru.spcex.clearing.backendapi.controller.utils.MatcherFactory.using @WebMvcTest//(controllers = DeleteCompanyController.class) //@TestPropertySource(properties = "spring.config.location=D:/repo/mfd/clearing/clearing-parent/backend-api/src/main/resources/") public abstract class AbstractControllerTest { - protected static final MatcherFactory.Matcher BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(BaseRequest.class); - protected static final MatcherFactory.Matcher CUD_RESPONSE_MATCHER = usingIgnoringFieldsComparator(CudResponse.class); + protected static final MatcherFactoryImdg.Matcher BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(BaseRequest.class); + protected static final MatcherFactoryImdg.Matcher CUD_RESPONSE_MATCHER = usingIgnoringFieldsComparator(CudResponse.class); protected static final AtomicLong currentId = new AtomicLong(); private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter(); diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java index 91351d88d..9d92d02c0 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java @@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class BankAccountControllerTest extends AbstractControllerTest { private static final String REST_URL = "/securities/bank-accounts/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java index 9c868d3b8..513fd21b0 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java @@ -15,7 +15,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class EditClearingMemberCategoryControllerTest extends AbstractControllerTest { private static final String REST_URL = "/clearing-member-categories/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java index b503dfaf8..305ea3263 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java @@ -24,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class EditCompanyInfoControllerTest extends AbstractControllerTest { private static final String REST_URL = "/company-infos/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java index 7368196d8..a84ecfed5 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java @@ -14,7 +14,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class EditCompanySymbolControllerTest extends AbstractControllerTest { private static final String REST_URL = "/company-symbols/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java index 3f256dc8f..6d0fa2f85 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java @@ -15,7 +15,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class EditContactControllerTest extends AbstractControllerTest { private static final String REST_URL = "/contacts/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java index af83388aa..6a99f321c 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java @@ -14,7 +14,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class RelationControllerTest extends AbstractControllerTest { private static final String REST_URL = "/relations/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java index 708cb12c3..6fd8344ed 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class NotificationControllerTest extends AbstractControllerTest { private static final String REST_URL = "/notifications/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java index 83d4ebcef..925b3d210 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java @@ -16,7 +16,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class SessionControllerTest extends AbstractControllerTest { private static final String REST_URL = "/sessions/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java index 1689c06ba..ef55f77f3 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class PaymentInstructionControllerTest extends AbstractControllerTest { private static final String REST_URL = "/payment-instructions/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java index 85ac5f57b..dde70e1e8 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java @@ -29,8 +29,8 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.readValue; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.readValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class LauncherControllerTest extends AbstractControllerTest { private static final String REST_URL = "/launchers/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java index c7759e880..cdbac036e 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class PlannerAllTodayControllerTest extends AbstractControllerTest { private static final String REST_URL = "/schedule/planners-all-today/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java index 688a0b946..e107dab46 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class PlannerControllerTest extends AbstractControllerTest { private static final String REST_URL = "/schedule/planners/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java index 96f1290c0..90f222444 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java @@ -18,7 +18,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.readValue; +import static ru.spcex.clearing.imdg.JsonUtil.readValue; class UserControllerTest extends AbstractControllerTest { public static final String REST_URL = "/users/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java index 8c6fd458b..0a418d31c 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java @@ -16,7 +16,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.imdg.JsonUtil.writeValue; class StatementControllerTest extends AbstractControllerTest { public static final String REST_URL = "/statements/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/JsonUtil.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/JsonUtil.java deleted file mode 100644 index cfbac9b79..000000000 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/JsonUtil.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.spcex.clearing.backendapi.controller.utils; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectReader; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static ru.spcex.clearing.backendapi.controller.config.Jackson2HttpConverterTestConfig.JacksonObjectMapper.getMapper; - -public class JsonUtil { - - public static List readValues(String json, Class clazz) { - ObjectReader reader = getMapper().readerFor(clazz); - try { - return reader.readValues(json).readAll(); - } catch (IOException e) { - throw new IllegalArgumentException("Invalid read array from JSON:\n'" + json + "'", e); - } - } - - public static T readValue(String json, Class clazz) { - try { - return getMapper().readValue(json, clazz); - } catch (IOException e) { - throw new IllegalArgumentException("Invalid read from JSON:\n'" + json + "'", e); - } - } - - public static String writeValue(T obj) { - try { - return getMapper().writeValueAsString(obj); - } catch (JsonProcessingException e) { - throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e); - } - } - - public static String writeIgnoreProps(T obj, String... ignoreProps) { - Map map = getMapper().convertValue(obj, new TypeReference<>() { - }); - map.keySet().removeAll(Set.of(ignoreProps)); - return writeValue(map); - } -} \ No newline at end of file diff --git a/clearing-parent/pom.xml b/clearing-parent/pom.xml index 7f495921e..ee4e84e2f 100644 --- a/clearing-parent/pom.xml +++ b/clearing-parent/pom.xml @@ -34,6 +34,7 @@ scheduler-service clearing-service registry-service + test-clearing diff --git a/clearing-parent/test-clearing/pom.xml b/clearing-parent/test-clearing/pom.xml new file mode 100644 index 000000000..6cd40dfc1 --- /dev/null +++ b/clearing-parent/test-clearing/pom.xml @@ -0,0 +1,77 @@ + + 4.0.0 + + ru.spcex.clearing + clearing-parent + SPCEX-1.0.0.0 + + test-clearing + Test-clearing + + + org.springframework.boot + spring-boot-starter-web + + + ru.spcex.platform + platform-imdg-api + + + ru.spcex.platform + platform-messaging + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework + spring-test + test + + + org.skyscreamer + jsonassert + test + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + org.reflections + reflections + 0.9.11 + + + org.springframework.boot + spring-boot-test-autoconfigure + test + + + org.mockito + mockito-core + + + org.springframework + spring-test + + + org.assertj + assertj-core + 3.23.1 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + SPCEX-1.0.0.0 + diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/JsonUtil.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/JsonUtil.java new file mode 100644 index 000000000..71efc1b6c --- /dev/null +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/JsonUtil.java @@ -0,0 +1,73 @@ +package ru.spcex.clearing.imdg; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +public class JsonUtil { + + public static List readValues(String json, Class clazz) { + ObjectReader reader = JacksonObjectMapper.getMapper().readerFor(clazz); + try { + return reader.readValues(json).readAll(); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid read array from JSON:\n'" + json + "'", e); + } + } + + public static T readValue(String json, Class clazz) { + try { + return JacksonObjectMapper.getMapper().readValue(json, clazz); + } catch (IOException e) { + throw new IllegalArgumentException("Invalid read from JSON:\n'" + json + "'", e); + } + } + + public static String writeValue(T obj) { + try { + return JacksonObjectMapper.getMapper().writeValueAsString(obj); + } catch (JsonProcessingException e) { + throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e); + } + } + + public static String writeIgnoreProps(T obj, String... ignoreProps) { + Map map = JacksonObjectMapper.getMapper().convertValue(obj, new TypeReference<>() { + }); + map.keySet().removeAll(Set.of(ignoreProps)); + return writeValue(map); + } + + public static class JacksonObjectMapper extends ObjectMapper { + private static final ObjectMapper MAPPER = new JacksonObjectMapper(); + + private JacksonObjectMapper() { + //настройки Ильи + configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); + //модуль для корректной сериализации LocalDateTime в поля JSON - JavaTimeModule модуль библиотеки jackson-datatype-jsr310 + registerModule(new JavaTimeModule()); + configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + //запрещаем доступ ко всем полям и методам класса и потом разрешаем доступ только к полям, нужны чтобы не было лишних полей из-за методов как: public ActionType getActionType() у BankAccountNewAction + setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); + setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + //не сериализуем null-поля +// setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + public static ObjectMapper getMapper() { + return MAPPER; + } + } +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/MatcherFactory.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryImdg.java similarity index 84% rename from clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/MatcherFactory.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryImdg.java index c72317938..ac61b25cd 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/MatcherFactory.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryImdg.java @@ -1,5 +1,6 @@ -package ru.spcex.clearing.backendapi.controller.utils; +package ru.spcex.clearing.imdg; +import org.assertj.core.api.Assertions; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; @@ -8,15 +9,13 @@ import java.io.UnsupportedEncodingException; import java.util.List; import java.util.function.BiConsumer; -import static org.assertj.core.api.Assertions.assertThat; - /** * Factory for creating test matchers. *

* Comparing actual and expected objects via AssertJ * Support converting json MvcResult to objects for comparation. */ -public class MatcherFactory { +public class MatcherFactoryImdg { public static Matcher usingAssertions(Class clazz, BiConsumer assertion, BiConsumer, Iterable> iterableAssertion) { return new Matcher<>(clazz, assertion, iterableAssertion); @@ -24,14 +23,14 @@ public class MatcherFactory { public static Matcher usingEqualsComparator(Class clazz) { return usingAssertions(clazz, - (a, e) -> assertThat(a).isEqualTo(e), - (a, e) -> assertThat(a).isEqualTo(e)); + (a, e) -> Assertions.assertThat(a).isEqualTo(e), + (a, e) -> Assertions.assertThat(a).isEqualTo(e)); } public static Matcher usingIgnoringFieldsComparator(Class clazz, String... fieldsToIgnore) { return usingAssertions(clazz, - (a, e) -> assertThat(a).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(e), - (a, e) -> assertThat(a).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(e)); + (a, e) -> Assertions.assertThat(a).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(e), + (a, e) -> Assertions.assertThat(a).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(e)); } public static class Matcher { diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/TestUtils.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/TestUtils.java similarity index 98% rename from clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/TestUtils.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/TestUtils.java index 45091310f..9c109a595 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/TestUtils.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/TestUtils.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.backendapi.controller.utils; +package ru.spcex.clearing.imdg; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/pom.xml b/pom.xml index b5e15a784..e21bc656f 100644 --- a/pom.xml +++ b/pom.xml @@ -104,6 +104,11 @@ security-util ${global.project.version} + + ru.spcex.clearing + test-clearing + ${global.project.version} + ru.spcex.platform From ade79ed6c6d4a143e95c32bf643c0c0c0276767d Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 19:09:41 +0300 Subject: [PATCH 74/90] CompanySymbolNotExistRule added --- .../validation/CompanyValidationConfig.java | 17 ++++++--- .../clearing/company/error/CompanyErrors.java | 1 + .../validation/CompanySymbolNotExistRule.java | 35 +++++++++++++++++++ .../platform/enumeration/CompanySymbol.java | 2 +- 4 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java index 6e90cdbee..b31127875 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java @@ -5,14 +5,17 @@ import org.springframework.context.annotation.Configuration; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.company.validation.CompanySymbolNotExistRule; 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.CompanyInfoUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; 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.CompanySymbol; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; @@ -32,28 +35,32 @@ public class CompanyValidationConfig { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(companyNewRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbols); addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); addImdg.accept(IMDGDistributedNames.Map_Company); - return new ValidatorImpl<>(context - , + return new ValidatorImpl<>(context, FieldRequiredRule.instance("shortName", CompanyNewRequest::getShortName, CompanyErrors.RequiredFieldEmpty), FieldRequiredRule.instance("companySymbol", CompanyNewRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), FieldRequiredRule.instance("companySymbolValue", CompanyNewRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), -// FieldRequiredRule.instance("workflowStatus", CompanyNewRequest::getWorkflowStatus, CompanyErrors.RequiredFieldEmpty), - DictionaryPresentRule.instance("workflowStatus", CompanyNewRequest::getWorkflowStatus, IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.WrongFieldValue), + EnumPresentRule.instance("companySymbol", + CompanyNewRequest::getCompanySymbol, + CompanySymbol.values(), + CompanyErrors.WrongFieldValue, + CompanyErrors.RequiredFieldEmpty), DictionaryPresentRule.instance("companySymbol", CompanyNewRequest::getCompanySymbol, IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class, CompanyErrors.RequiredFieldEmpty, - CompanyErrors.WrongFieldValue) + CompanyErrors.WrongFieldValue), + new CompanySymbolNotExistRule() ); }; } 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 02ad9886e..d36d2104f 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 @@ -20,6 +20,7 @@ public enum CompanyErrors implements IErrorEnumId { CategoryNotFound(3016L), // Категория компании %s не найдена. CategoryAlreadySet(3017L), // Компании %s уже присвоена категория %s. CompanyAlreadyHasLiabilities(3018L), // У компании %s присутствуют обязательства. + CompanyWithCompanySymbolAlreadyExist(3019L), // Компания с %s = %s уже создана" (где первый %s - companySymbol, второй %s - companySymbolValue) EditCompanySymbols(3020L), // Тип реквизита компании %s не может быть изменен. EditContactType(3021L) // Тип контакта компании %s не может быть изменен. ; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java new file mode 100644 index 000000000..8ecb5706c --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java @@ -0,0 +1,35 @@ +package ru.spcex.clearing.company.validation; + +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Collection; +import java.util.Optional; + +/** + * Проверка наличия компании с переданными в запросе companySymbol и companySymbolCode (реквизиты) + */ +public class CompanySymbolNotExistRule implements IValidationRule> { + @Override + public Optional validate(ImdgValidationContext context) { + CompanyNewRequest request = context.getValidatedObject(); + String companySymbolCode = request.getCompanySymbol(); + String companySymbolValue = request.getCompanySymbolValue(); + Imdg companySymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + ImdgPredicateBuilder pb = companySymbolsImdg.predicateBuilder(); + ImdgPredicate companySymbolPredicate = pb.equals("companySymbol", companySymbolCode); + ImdgPredicate companySymbolValuePredicate = pb.equals("companySymbolValue", companySymbolValue); + ImdgPredicate andPredicate = pb.and(companySymbolPredicate, companySymbolValuePredicate); + Collection companySymbols = companySymbolsImdg.getCollectionObjectsByPredicate(andPredicate); + if (companySymbols.isEmpty()) return Optional.empty(); + return of(CompanyErrors.CompanyWithCompanySymbolAlreadyExist, companySymbolCode, companySymbolValue); + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java index fe03542c9..7cd2eee6e 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/CompanySymbol.java @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum CompanySymbol implements IEnumKey { - INN("INN"), BIC("BIC"), + INN("INN"), BIC("BIC"), CIO("CIO"), UUID("UUID"), TRDC("TRDC"), CLRC("CLRC"), RGRC("RGRC"); private final String key; From 0cbbe2a05b37b9ef0bbaf51c9b47afae09d1200d Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 19:30:01 +0300 Subject: [PATCH 75/90] CompanyServiceTest, add test for newCompany fail --- .../config/validation/ValidationConfig.java | 2 + .../validation/CompanySymbolNotExistRule.java | 6 +++ .../company/service/CompanyServiceTest.java | 46 ++++++++++++++++++- .../clearing/company/utils/TestUtils.java | 26 +++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) 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 1a922efe6..a076fa999 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 @@ -3,6 +3,7 @@ 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.CompanySymbols; import ru.clearing.classes.statics.data.generated.ClearingMemberCategory; import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.classes.statics.data.profile.ProfileDocument; @@ -35,6 +36,7 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_Contact, Contact.class); addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CorporationSoleTypeDictionary, CorporationSoleTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CountryCodeDictionary, CountryCodeDictionary.class); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java index 8ecb5706c..b2d477732 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java @@ -4,6 +4,7 @@ import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.platform.enumeration.CompanySymbol; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; @@ -11,6 +12,7 @@ import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.validation.IValidationRule; +import java.util.Arrays; import java.util.Collection; import java.util.Optional; @@ -22,6 +24,10 @@ public class CompanySymbolNotExistRule implements IValidationRule validate(ImdgValidationContext context) { CompanyNewRequest request = context.getValidatedObject(); String companySymbolCode = request.getCompanySymbol(); + if (!Arrays.asList(CompanySymbol.INN.getKey(), + CompanySymbol.CIO.getKey(), + CompanySymbol.UUID.getKey()).contains(companySymbolCode)) return Optional.empty(); + String companySymbolValue = request.getCompanySymbolValue(); Imdg companySymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); ImdgPredicateBuilder pb = companySymbolsImdg.predicateBuilder(); 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 2112c5b8d..9e6f01dae 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 @@ -14,6 +14,7 @@ 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.classes.statics.data.generated.ClearingMemberCategory; import ru.clearing.platform.dictionary.CompanySymbolDictionary; import ru.clearing.platform.dictionary.WorkflowStatusDictionary; @@ -22,6 +23,7 @@ import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; +import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.company.utils.MatcherFactory; import ru.spcex.clearing.company.utils.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -35,7 +37,7 @@ import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import javax.annotation.PostConstruct; - +import java.util.Arrays; import java.util.Map; import static org.mockito.Mockito.doReturn; @@ -67,6 +69,7 @@ class CompanyServiceTest { @Qualifier("hazelcastServiceTest") private HazelcastService hazelcastServiceTest; private Imdg companyImdg; + private Imdg companySymbolsImdg; private Imdg workflowStatusDictionaryImdg; @Captor @@ -78,6 +81,7 @@ class CompanyServiceTest { private void init() { hazelcastServiceTest.waitAvailable(); 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(); @@ -99,6 +103,11 @@ class CompanyServiceTest { 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); } TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); @@ -178,4 +187,39 @@ class CompanyServiceTest { 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) companyService.getConsumer(), DESTINATION_COMPANY_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenTryAddRecordAndCheckError(ID, + mockProducer, + producerRecord, + String.valueOf(CompanyErrors.CompanyWithCompanySymbolAlreadyExist.getId()), + Arrays.asList("CIO", "test_value")); + + Company resultNew = companyImdg.getSingleObjectByFieldValues(Map.of("ShortName", "ClrIPO")); + Assertions.assertNull(resultNew); + } } \ No newline at end of file diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java index 17cfeb9ca..1e6270839 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java @@ -13,12 +13,14 @@ 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.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -52,6 +54,30 @@ public class TestUtils { BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); } + public static void waitingWhenTryAddRecordAndCheckError(Long id, + MockProducer mockProducer, + ArgumentCaptor producerRecord, + String errorCode, + List errorMessageArgs) { + BaseRequest predictableBaseRequest = new BaseRequest<>(); + predictableBaseRequest.setId(id); + predictableBaseRequest.setActionType(ActionType.SYSTEM); + RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate(); + requestInfoUpdate.setId(id); + requestInfoUpdate.setStatus(Status.Error); + String errorsMessage = "(%s) args [%s]".formatted(errorCode, String.join(", ", errorMessageArgs)); + requestInfoUpdate.setMessage(errorsMessage); + predictableBaseRequest.setRequestPayload(requestInfoUpdate); + + //waiting for kafka producer send message (finale event) + verify(mockProducer, timeout(30_000L).times(1)) + .send(producerRecord.capture()); + + BaseRequest baseRequestResult = (BaseRequest) producerRecord.getValue().value(); + assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic()); + BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); + } + public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) { TopicPartition tp = new TopicPartition(topic, partition); HashMap startOffsets = new HashMap<>(); From 17ca798fef2c61738b677125a3f0203e3652bf2b Mon Sep 17 00:00:00 2001 From: akulikov Date: Thu, 6 Apr 2023 19:56:12 +0300 Subject: [PATCH 76/90] CouponPeriodService: fix new/update request --- .../service/cud/CouponPeriodService.java | 10 ++-- .../validation/ValidationProvider.java | 9 +++- .../service/CouponPeriodServiceTest.java | 49 +++++++++++++------ .../securitites/CouponPeriodNewRequest.java | 23 +++++++++ .../CouponPeriodUpdateRequest.java | 23 +++++++++ 5 files changed, 96 insertions(+), 18 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java index 96e55f284..e6bf52ebe 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java @@ -66,6 +66,8 @@ public class CouponPeriodService extends QueueConsumer implements InitializingBe CouponPeriod couponPeriod = new CouponPeriod(); couponPeriod.setId(idGenerator.nextId()); couponPeriod.setSecurityId(req.getSecurityId()); + couponPeriod.setCouponRate(req.getCouponRate()); + couponPeriod.setNumber(req.getNumber()); couponPeriod.setPeriodEndDate(req.getPeriodEndDate()); couponPeriod.setPeriodStartDate(req.getPeriodStartDate()); couponPeriodImdg.insert(couponPeriod); @@ -80,9 +82,11 @@ public class CouponPeriodService extends QueueConsumer implements InitializingBe RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.couponPeriodUpdateValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; - CouponPeriod couponPeriod = couponPeriodImdg.getSingleObjectBySQL(String.format("securityId = %s", req.getSecurityId())); - couponPeriod.setPeriodEndDate(req.getPeriodEndDate()); - couponPeriod.setPeriodStartDate(req.getPeriodStartDate()); + CouponPeriod couponPeriod = couponPeriodImdg.getSingleObjectByID(req.getId()); + if (req.getCouponRate() != null) couponPeriod.setCouponRate(req.getCouponRate()); + if (req.getNumber() != null) couponPeriod.setNumber(req.getNumber()); + if (req.getPeriodEndDate() != null) couponPeriod.setPeriodEndDate(req.getPeriodEndDate()); + if (req.getPeriodStartDate() != null) couponPeriod.setPeriodStartDate(req.getPeriodStartDate()); couponPeriodImdg.update(couponPeriod); return null; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index 6aedc564f..2dfae6757 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -7,6 +7,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.*; import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.clearing.securities.validation.rule.*; import ru.spcex.clearing.validation.common.rules.EndDtAfterStartDtRule; +import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -264,7 +265,13 @@ public class ValidationProvider { CouponPeriodNewRequest::getPeriodEndDate, SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue, false), - CouponPeriodNewValidationRule.CouponPeriodNotExists + CouponPeriodNewValidationRule.CouponPeriodNotExists, + FieldRequiredRule.instance("couponRate", + CouponPeriodNewRequest::getCouponRate, + SecuritiesError.RequiredFieldIsEmpty), + FieldRequiredRule.instance("number", + CouponPeriodNewRequest::getNumber, + SecuritiesError.RequiredFieldIsEmpty) ); }; } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java index 295d403b0..c6cc8c02b 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java @@ -12,6 +12,7 @@ import ru.spcex.clearing.securities.service.cud.CouponPeriodService; import ru.spcex.clearing.securities.utils.MatcherFactory; import javax.annotation.PostConstruct; +import java.math.BigDecimal; import java.time.LocalDate; import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; @@ -46,10 +47,14 @@ public class CouponPeriodServiceTest extends AbstractServiceTest { currencyPrediction.setSecurityId(securityId); currencyPrediction.setPeriodEndDate(LocalDate.now()); currencyPrediction.setPeriodStartDate(LocalDate.ofEpochDay(0)); + currencyPrediction.setCouponRate(BigDecimal.TEN); + currencyPrediction.setNumber(Long.MAX_VALUE); final CouponPeriodNewRequest request = new CouponPeriodNewRequest(); request.setSecurityId(securityId); request.setPeriodEndDate(LocalDate.now()); request.setPeriodStartDate(LocalDate.ofEpochDay(0)); + request.setCouponRate(BigDecimal.TEN); + request.setNumber(Long.MAX_VALUE); //ACT @@ -74,27 +79,43 @@ public class CouponPeriodServiceTest extends AbstractServiceTest { public void testUpdateCurrency() { clearAllInImdg(couponPeriodImdg); final String TOPIC = Consts.DESTINATION_COUPON_PERIOD_UPDATE; - final CouponPeriod currencyPrediction = new CouponPeriod(); - currencyPrediction.setSecurityId(securityId); - currencyPrediction.setPeriodEndDate(LocalDate.ofEpochDay(0)); - currencyPrediction.setPeriodStartDate(LocalDate.ofEpochDay(0)); - couponPeriodImdg.insert(currencyPrediction); - final CouponPeriodNewRequest request = new CouponPeriodNewRequest(); - currencyPrediction.setPeriodEndDate(LocalDate.now()); + final CouponPeriod existCouponPeriod = new CouponPeriod(); + existCouponPeriod.setSecurityId(securityId); + existCouponPeriod.setCouponRate(BigDecimal.ZERO); + existCouponPeriod.setNumber(Long.MIN_VALUE); + existCouponPeriod.setPeriodEndDate(LocalDate.ofEpochDay(0)); + existCouponPeriod.setPeriodStartDate(LocalDate.ofEpochDay(0)); + Long id = couponPeriodImdg.insert(existCouponPeriod); + + LocalDate testStartDate = LocalDate.now(); + LocalDate testEndDate = LocalDate.now().minusDays(10); + + final CouponPeriod predictableCoupon = new CouponPeriod(); + predictableCoupon.setSecurityId(securityId); + predictableCoupon.setCouponRate(BigDecimal.TEN); + predictableCoupon.setNumber(Long.MAX_VALUE); + predictableCoupon.setPeriodEndDate(testStartDate); + predictableCoupon.setPeriodStartDate(testEndDate); + + final CouponPeriodUpdateRequest request = new CouponPeriodUpdateRequest(); + predictableCoupon.setPeriodEndDate(LocalDate.now()); + request.setId(id); + request.setCouponRate(BigDecimal.TEN); + request.setNumber(Long.MAX_VALUE); request.setSecurityId(securityId); - request.setPeriodEndDate(LocalDate.now()); - request.setPeriodStartDate(LocalDate.ofEpochDay(0)); + request.setPeriodEndDate(testStartDate); + request.setPeriodStartDate(testEndDate); //ACT - String jsonString = getJsonStringForUPDATE(request, ID); + String jsonString = getJsonStringForUPDATE(request, id); addRecordToKafka((MockConsumer) couponPeriodService.getConsumer(), TOPIC, PARTITION, 0, jsonString); //ASSERT - waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + waitingWhenAddedRecordAndCheckIt(id, mockProducer, producerRecord); - CouponPeriod result = couponPeriodImdg.getSingleObjectBySQL(String.format("securityId = %s", currencyPrediction.getSecurityId())); - currencyPrediction.setId(result.getId()); - COUPON_PERIOD_MATCHER.assertMatch(result, currencyPrediction); + CouponPeriod result = couponPeriodImdg.getSingleObjectBySQL(String.format("securityId = %s", predictableCoupon.getSecurityId())); + predictableCoupon.setId(result.getId()); + COUPON_PERIOD_MATCHER.assertMatch(result, predictableCoupon); } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java index 23118e3cb..6c1d706f1 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java @@ -3,15 +3,22 @@ package ru.spcex.clearing.platform.messaging.domain.cud.securitites; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; +import java.math.BigDecimal; import java.time.LocalDate; public class CouponPeriodNewRequest { @JsonProperty public Long securityId; @JsonProperty + @JsonDeserialize(using = NumberDeserializers.BigDecimalDeserializer.class) + public BigDecimal couponRate; + @JsonProperty + public Long number; + @JsonProperty @JsonSerialize(using = LocalDateSerializer.class) @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate periodEndDate; @@ -43,4 +50,20 @@ public class CouponPeriodNewRequest { public void setPeriodStartDate(LocalDate periodStartDate) { this.periodStartDate = periodStartDate; } + + public BigDecimal getCouponRate() { + return couponRate; + } + + public void setCouponRate(BigDecimal couponRate) { + this.couponRate = couponRate; + } + + public Long getNumber() { + return number; + } + + public void setNumber(Long number) { + this.number = number; + } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java index 96a344661..fb0bf2a1b 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.java @@ -3,10 +3,12 @@ package ru.spcex.clearing.platform.messaging.domain.cud.securitites; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; import ru.spcex.platform.classes.base.interfaces.WithId; +import java.math.BigDecimal; import java.time.LocalDate; public class CouponPeriodUpdateRequest implements WithId { @@ -15,6 +17,11 @@ public class CouponPeriodUpdateRequest implements WithId { @JsonProperty public Long securityId; @JsonProperty + @JsonDeserialize(using = NumberDeserializers.BigDecimalDeserializer.class) + public BigDecimal couponRate; + @JsonProperty + public Long number; + @JsonProperty @JsonSerialize(using = LocalDateSerializer.class) @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate periodEndDate; @@ -56,4 +63,20 @@ public class CouponPeriodUpdateRequest implements WithId { public void setPeriodStartDate(LocalDate periodStartDate) { this.periodStartDate = periodStartDate; } + + public BigDecimal getCouponRate() { + return couponRate; + } + + public void setCouponRate(BigDecimal couponRate) { + this.couponRate = couponRate; + } + + public Long getNumber() { + return number; + } + + public void setNumber(Long number) { + this.number = number; + } } From 28f47e8ebd1f795bb096caa83b0618ba8c07b3b3 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 7 Apr 2023 10:54:48 +0300 Subject: [PATCH 77/90] =?UTF-8?q?validateTillFirstError=20=D1=83=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D0=BD=D1=8C=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE?= =?UTF-8?q?=D0=BA=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20-=20warn.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/spcex/clearing/validation/common/ValidationHelper.java | 2 +- .../clearing/platform/messaging/service/QueueConsumer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java index 5c57061cf..d8024bc4e 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java @@ -35,7 +35,7 @@ public class ValidationHelper { Optional validationError = validator.tillFirstError(); if (validationError.isPresent()) { String errorMsg = messageResolver.resolve(validationError.get()); - log.error("validation error for {} error={}, id={}: {}", req.getClass().getSimpleName(), validationError.get().getSubject(), userRequest.getId(), errorMsg); + log.warn("validation error for {} error={}, id={}: {}", req.getClass().getSimpleName(), validationError.get().getSubject(), userRequest.getId(), errorMsg); return new RequestInfoUpdate() .setId(userRequest.getId()) .setStatus(Status.Error) 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 706b50f36..83a2d7ca5 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 @@ -181,7 +181,7 @@ public class QueueConsumer implements AutoCloseable { Optional validationError = validator.tillFirstError(); if (validationError.isPresent()) { String errorMsg = messageResolver.resolve(validationError.get()); - log.error("validation error for {} error={}, id={}: {}", req.getClass().getSimpleName(), validationError.get().getSubject(), userRequest.getId(), errorMsg); + log.warn("validation error for {} error={}, id={}: {}", req.getClass().getSimpleName(), validationError.get().getSubject(), userRequest.getId(), errorMsg); return new RequestInfoUpdate() .setId(userRequest.getId()) .setStatus(Status.Error) From 3fcf40d94a2b867601989830c1f6c93d330e7288 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 7 Apr 2023 10:55:02 +0300 Subject: [PATCH 78/90] company-service: RequestHelper to spring bean --- .../company/config/BeanConfiguration.java | 10 +++++++ .../company/service/CompanyInfoService.java | 5 ++-- .../service/CompanyRoleSetService.java | 6 ++--- .../company/service/CompanyService.java | 9 ++++--- .../clearing/company/util/RequestHelper.java | 27 ++++++++++++++----- 5 files changed, 39 insertions(+), 18 deletions(-) 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 cec73efc2..dca027316 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 @@ -1,7 +1,10 @@ package ru.spcex.clearing.company.config; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import ru.spcex.clearing.company.util.RequestHelper; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; @@ -18,4 +21,11 @@ public class BeanConfiguration { UserRoleVerification userRoleVerification(ImdgProvider imdg) { return new UserRoleVerification(imdg); } + + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public RequestHelper requestHelper(IMessageResolver messageResolver) { + return new RequestHelper(messageResolver); + } + } 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 00d9f92fa..0a85810af 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 @@ -23,7 +23,6 @@ import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; -import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; @@ -43,7 +42,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea @Autowired public CompanyInfoService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, CompanyService companyService, - IMessageResolver messageResolver, ValidationHelper validationHelper, + RequestHelper requestHelper, ValidationHelper validationHelper, UserRoleVerification userRoleVerification, @Qualifier("CompanyInfoUpdateRequestValidator") Function companyInfoUpdateRequestValidator) { @@ -52,8 +51,8 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.validationHelper = validationHelper; this.userRoleVerification = userRoleVerification; - this.requestHelper = new RequestHelper(log, messageResolver); this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator; + this.requestHelper = requestHelper.setLogger(log); } @Override 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 ee8cef564..710d43e59 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 @@ -6,7 +6,6 @@ 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.CompanyRoleSet; import ru.spcex.clearing.company.error.CompanyErrors; @@ -26,7 +25,6 @@ import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ValidationException; -import ru.spcex.platform.utils.validation.IValidator; import java.util.Map; @@ -49,7 +47,7 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing @Autowired public CompanyRoleSetService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, - IMessageResolver messageResolver, + RequestHelper requestHelper, UserRoleVerification userRoleVerification, ValidationHelper validationHelper // @Qualifier("CompanyRoleSetRequestValidator") @@ -58,12 +56,12 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; this.messageResolver = messageResolver; - this.requestHelper = new RequestHelper(log, messageResolver); this.companyRoleSetMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); this.idSequence = imdgProvider.getImdgIdGenerator(); this.userRoleVerification = userRoleVerification; this.validationHelper = validationHelper; // this.companyDeleteRequestValidator = companyDeleteRequestValidator; + this.requestHelper = requestHelper.setLogger(log); } @Override 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 98ac9eb3b..4e1bfd5c0 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 @@ -21,7 +21,9 @@ 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.*; +import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.platform.enumeration.UserRole; +import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -58,7 +60,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, - IMessageResolver messageResolver, + RequestHelper requestHelper, UserRoleVerification userRoleVerification, ValidationHelper validationHelper, @Qualifier("companyNewRequestValidator") @@ -74,8 +76,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { ) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; - this.messageResolver = messageResolver; - this.requestHelper = new RequestHelper(log, messageResolver); + this.requestHelper = requestHelper.setLogger(log); this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); 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 3e9bc8ad5..a6609abbb 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 @@ -6,7 +6,6 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.platform.utils.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IEnumId; import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ClearingBaseException; @@ -16,7 +15,7 @@ import java.util.Objects; /** * Упрощает обработку ошибок во время обработки реквестов. - * Передаёт регламинтированные ошибки из ClearingBaseException. + * Передаёт регламентированные ошибки из ClearingBaseException. * * Пример: * callback(CompanyNewRequest.class) @@ -24,9 +23,14 @@ import java.util.Objects; * .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); */ public class RequestHelper { - protected final Logger log; + protected Logger log = null; protected final IMessageResolver messageResolver; + public RequestHelper(IMessageResolver messageResolver) { + Objects.requireNonNull(messageResolver); + this.messageResolver = messageResolver; + } + public RequestHelper(Logger log, IMessageResolver messageResolver) { Objects.requireNonNull(log); Objects.requireNonNull(messageResolver); @@ -44,12 +48,15 @@ public class RequestHelper { */ public > RequestInfoUpdate requestFunction(RequestCommand command, T userRequest) { try { - log.debug("{} request received, BaseRequest.id = {}", userRequest.getClass().getSimpleName(), userRequest.getId()); + if (log != null) + log.debug("{} request received, BaseRequest.id = {}", userRequest.getClass().getSimpleName(), userRequest.getId()); RequestInfoUpdate reply = command.command(userRequest); - log.trace("Reply on request {}: {}" , userRequest.getId(), reply); + if (log != null) + log.trace("Reply on request {}: {}" , userRequest.getId(), reply); return reply; } catch (ClearingBaseException expectedE) { - log.trace("{} return expected exception: {}", command, expectedE.toString()); + if (log != null) + log.trace("{} return expected exception: {}", command, expectedE.toString()); String message = expectedE.getEnumMsg() == null ? expectedE.getMessage() : messageResolver.resolve(expectedE.getEnumMsg()); @@ -58,7 +65,8 @@ public class RequestHelper { .setStatus(Status.Error) .setMessage(message); } catch (Exception unexpectedE) { - log.error("Error at {}: {} ", command, ExceptionUtils.getStackTrace(unexpectedE)); + if (log != null) + log.error("Error at {}: {} ", command, ExceptionUtils.getStackTrace(unexpectedE)); String message = messageResolver.resolve(new EnumMessage(CompanyErrors.GeneralError)); return new RequestInfoUpdate() .setId(userRequest.getId()) @@ -83,4 +91,9 @@ public class RequestHelper { public interface RequestCommand { RequestInfoUpdate command(T arg) throws ClearingBaseException; } + + public RequestHelper setLogger(Logger log) { + this.log = log; + return this; + } } From 4594540d4040dc50ccc9357281db0e0b99748079 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 7 Apr 2023 11:17:16 +0300 Subject: [PATCH 79/90] company-service: RequestHelper fix logger --- .../clearing/company/util/RequestHelper.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) 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 a6609abbb..f134ec949 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 @@ -1,6 +1,7 @@ package ru.spcex.clearing.company.util; 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; @@ -23,7 +24,7 @@ import java.util.Objects; * .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); */ public class RequestHelper { - protected Logger log = null; + protected Logger log = LoggerFactory.getLogger(getClass()); protected final IMessageResolver messageResolver; public RequestHelper(IMessageResolver messageResolver) { @@ -48,15 +49,12 @@ public class RequestHelper { */ public > RequestInfoUpdate requestFunction(RequestCommand command, T userRequest) { try { - if (log != null) - log.debug("{} request received, BaseRequest.id = {}", userRequest.getClass().getSimpleName(), userRequest.getId()); + log.debug("{} request received, BaseRequest.id = {}", userRequest.getClass().getSimpleName(), userRequest.getId()); RequestInfoUpdate reply = command.command(userRequest); - if (log != null) - log.trace("Reply on request {}: {}" , userRequest.getId(), reply); + log.trace("Reply on request {}: {}" , userRequest.getId(), reply); return reply; } catch (ClearingBaseException expectedE) { - if (log != null) - log.trace("{} return expected exception: {}", command, expectedE.toString()); + log.trace("{} return expected exception: {}", command, expectedE.toString()); String message = expectedE.getEnumMsg() == null ? expectedE.getMessage() : messageResolver.resolve(expectedE.getEnumMsg()); @@ -65,8 +63,7 @@ public class RequestHelper { .setStatus(Status.Error) .setMessage(message); } catch (Exception unexpectedE) { - if (log != null) - log.error("Error at {}: {} ", command, ExceptionUtils.getStackTrace(unexpectedE)); + log.error("Error at {}: {} ", command, ExceptionUtils.getStackTrace(unexpectedE)); String message = messageResolver.resolve(new EnumMessage(CompanyErrors.GeneralError)); return new RequestInfoUpdate() .setId(userRequest.getId()) @@ -93,6 +90,7 @@ public class RequestHelper { } public RequestHelper setLogger(Logger log) { + if (log == null) return this; this.log = log; return this; } From 5366a7d79b3b97c12fb95e00bb2179baf66fc28f Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 7 Apr 2023 12:20:36 +0300 Subject: [PATCH 80/90] UserRoleVerification modification --- .../company/config/BeanConfiguration.java | 7 -- .../company/service/CompanyInfoService.java | 27 +--- .../service/CompanyRoleSetService.java | 19 +-- .../company/service/CompanyService.java | 20 +-- clearing-parent/security-util/pom.xml | 4 + .../util/security/UserRoleVerification.java | 117 +++++++++++------- 6 files changed, 89 insertions(+), 105 deletions(-) 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 dca027316..3bb06b41e 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,8 +5,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import ru.spcex.clearing.company.util.RequestHelper; -import ru.spcex.clearing.util.security.UserRoleVerification; -import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; @@ -17,11 +15,6 @@ public class BeanConfiguration { return new SimpleMessageResolver(); } - @Bean - UserRoleVerification userRoleVerification(ImdgProvider imdg) { - return new UserRoleVerification(imdg); - } - @Bean @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public RequestHelper requestHelper(IMessageResolver messageResolver) { 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 0a85810af..c23d47b1e 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 @@ -23,7 +23,6 @@ import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; -import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; @@ -43,14 +42,13 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea public CompanyInfoService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, CompanyService companyService, RequestHelper requestHelper, ValidationHelper validationHelper, - UserRoleVerification userRoleVerification, @Qualifier("CompanyInfoUpdateRequestValidator") Function companyInfoUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); this.companyService = companyService; this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.validationHelper = validationHelper; - this.userRoleVerification = userRoleVerification; + this.userRoleVerification = new UserRoleVerification(imdgProvider, UserRole.Admin, CompanyErrors.UserVerifyDenial); this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator; this.requestHelper = requestHelper.setLogger(log); } @@ -67,28 +65,15 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea } - protected void validateRole(BaseRequest req) throws ValidationException { - Long requestor = req.getUserId(); - if (requestor != null && !userRoleVerification.userHasRole(requestor, UserRole.Admin)) { - log.trace("User {} has no role to allow this action", requestor); - throw new ValidationException(CompanyErrors.UserVerifyDenial); - } else { - log.trace("Request without userId"); - } - } - public RequestInfoUpdate companyInfoUpdate(BaseRequest companyInfoReq) { CompanyInfoUpdateRequest req = companyInfoReq.getRequestPayload(); log.debug("{} received", req.getClass().getSimpleName()); { // Валидация, ValidationException - try { - validateRole(companyInfoReq); - } catch (ValidationException e) { - return requestHelper.makeErrorResponse(companyInfoReq, e.getEnumMsg()); - } - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyInfoReq, companyInfoUpdateRequestValidator); - if (requestInfoUpdate != null) - return requestInfoUpdate; + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyInfoReq); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(companyInfoReq, companyInfoUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; } synchronized (companyService) { Company company = companyMap.getSingleObjectByID(req.getId()); 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 710d43e59..e1b428cce 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 @@ -48,17 +48,15 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing public CompanyRoleSetService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, RequestHelper requestHelper, - UserRoleVerification userRoleVerification, ValidationHelper validationHelper // @Qualifier("CompanyRoleSetRequestValidator") // Function companyNewRequestValidator, ) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; - this.messageResolver = messageResolver; this.companyRoleSetMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = userRoleVerification; + this.userRoleVerification = new UserRoleVerification(imdgProvider, UserRole.Admin, CompanyErrors.UserVerifyDenial); this.validationHelper = validationHelper; // this.companyDeleteRequestValidator = companyDeleteRequestValidator; this.requestHelper = requestHelper.setLogger(log); @@ -79,22 +77,11 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing init(); } - protected void validateRole(BaseRequest req) throws ValidationException { - Long requestor = req.getUserId(); - if (requestor != null && !userRoleVerification.userHasRole(requestor, UserRole.Admin)) { - log.trace("User {} has no role to allow this action", requestor); - throw new ValidationException(CompanyErrors.UserVerifyDenial); - } else { - log.trace("Request without userId"); - } - } - - private RequestInfoUpdate createCompanyRoleSet(BaseRequest companyRoleNewRequestBaseRequest) throws ValidationException { CompanyRoleSetNewRequest req = companyRoleNewRequestBaseRequest.getRequestPayload(); log.debug("companyroleset-new request received, BaseRequest.id = {}", companyRoleNewRequestBaseRequest.getId()); { // Валидация, ValidationException - validateRole(companyRoleNewRequestBaseRequest); + userRoleVerification.validateRoleAndThrow(companyRoleNewRequestBaseRequest); // RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyRoleNewRequestBaseRequest, companyNewRequestValidator); // if (requestInfoUpdate != null) return requestInfoUpdate; } @@ -130,7 +117,7 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing CommonDeleteRequest request = companyRoleSetDeleteRequest.getRequestPayload(); log.debug("companyRoleSetDeleteRequest received id = {}", request.getId()); { // Валидация, ValidationException - validateRole(companyRoleSetDeleteRequest); + userRoleVerification.validateRoleAndThrow(companyRoleSetDeleteRequest); if (request.getId() == null) { return requestHelper.makeErrorResponse(companyRoleSetDeleteRequest, CompanyErrors.RequiredFieldEmpty, "id"); } 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 4e1bfd5c0..a7cec33f1 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 @@ -61,7 +61,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, RequestHelper requestHelper, - UserRoleVerification userRoleVerification, ValidationHelper validationHelper, @Qualifier("companyNewRequestValidator") Function companyNewRequestValidator, @@ -80,7 +79,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = userRoleVerification; + this.userRoleVerification = new UserRoleVerification(imdgProvider, UserRole.Admin, CompanyErrors.UserVerifyDenial); this.validationHelper = validationHelper; this.companyNewRequestValidator = companyNewRequestValidator; this.companyUpdateRequestValidator = companyUpdateRequestValidator; @@ -104,22 +103,11 @@ public class CompanyService extends QueueConsumer implements InitializingBean { init(); } - protected void validateRole(BaseRequest req) throws ValidationException { - Long requestor = req.getUserId(); - if (requestor != null && !userRoleVerification.userHasRole(requestor, UserRole.Admin)) { - log.trace("User {} has no role to allow this action", requestor); - throw new ValidationException(CompanyErrors.UserVerifyDenial); - } else { - log.trace("Request without userId"); - } - } - - private synchronized RequestInfoUpdate createCompany(BaseRequest companyNewRequestBaseRequest) throws ValidationException { CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); { // Валидация, ValidationException - validateRole(companyNewRequestBaseRequest); + userRoleVerification.validateRoleAndThrow(companyNewRequestBaseRequest); RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyNewRequestBaseRequest, companyNewRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } @@ -165,7 +153,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private synchronized RequestInfoUpdate updateCompany(BaseRequest companyUpdateRequestBaseRequest) throws ValidationException { CompanyNewRequest updateRequest = companyUpdateRequestBaseRequest.getRequestPayload(); { // Валидация, ValidationException - validateRole(companyUpdateRequestBaseRequest); + userRoleVerification.validateRoleAndThrow(companyUpdateRequestBaseRequest); RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyUpdateRequestBaseRequest, companyUpdateRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } @@ -246,7 +234,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { CommonDeleteRequest request = companyBlockRequestBaseRequest.getRequestPayload(); log.debug("CommonDeleteRequest (block request) received id = {}", request.getId()); { // Валидация, ValidationException - validateRole(companyBlockRequestBaseRequest); + userRoleVerification.validateRoleAndThrow(companyBlockRequestBaseRequest); RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyBlockRequestBaseRequest, companyDeleteRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } diff --git a/clearing-parent/security-util/pom.xml b/clearing-parent/security-util/pom.xml index 4a9abfe93..57332ac31 100644 --- a/clearing-parent/security-util/pom.xml +++ b/clearing-parent/security-util/pom.xml @@ -83,5 +83,9 @@ assertj-core test + + ru.spcex.platform + platform-messaging + \ No newline at end of file diff --git a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java index fcc2536ef..9cefe8add 100644 --- a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -2,17 +2,17 @@ package ru.spcex.clearing.util.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import ru.clearing.classes.objects.BusinessObject; -import ru.clearing.classes.statics.data.company.CompanyRoleSet; -import ru.clearing.classes.statics.data.user.User; import ru.clearing.classes.statics.data.user.UserRoleSession; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.platform.enumeration.Status; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; +import ru.spcex.platform.utils.error.ValidationException; import java.util.Collection; @@ -21,66 +21,93 @@ import java.util.Collection; *

* Основная проверка прав осуществляется на frontend-api, и использовать этот компонент дополнительно не требуется. */ -@Service public class UserRoleVerification { protected Logger log = LoggerFactory.getLogger(getClass()); - protected Imdg users; protected Imdg userRoleSessions; - protected Imdg companyRoleSet; + protected UserRole roleForVerification; + protected IErrorEnumId roleVerificationError; - @Autowired - public UserRoleVerification(ImdgProvider imdg) { + public UserRoleVerification(ImdgProvider imdg, UserRole roleForVerification, IErrorEnumId roleVerificationError) { userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); - companyRoleSet = imdg.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); + this.roleForVerification = roleForVerification; + this.roleVerificationError = roleVerificationError; } - public boolean userHasRole(Long userId, String userRole) { + protected boolean userHasRole(Long userId, IEnumKey role) { + return userHasRole(userId, role == null ? null : role.getKey()); + } + + protected boolean userHasRole(Long userId, String userRole) { String query = String.format("userId=%s and userRole=%s and status=%s", userId, userRole, Status.Active.getKey()); Collection roles = userRoleSessions.getCollectionIdsBySQL(query); log.trace("userHasRole: found {} roles by query: {}", roles.size(), query); - if (roles.isEmpty()) - return false; - //todo impl, use userRoleSessions - return true; - } - - public boolean userHasRole(Long userId, Long companyId, String userRole) { - String query = String.format("userId=%s and companyId=%s and userRole=%s and status=%s", - userId, companyId, userRole, Status.Active.getKey()); - Collection roles = userRoleSessions.getCollectionIdsBySQL(query); - log.trace("userHasRole: found {} roles by query: {}", roles.size(), query); - if (roles.isEmpty()) - return false; - //todo impl, use userRoleSessions - return true; + return !roles.isEmpty(); } - public boolean userHasRole(Long userId, IEnumKey role) { - return userHasRole(userId, role == null ? null : role.getKey()); + public void validateRoleAndThrow(BaseRequest req) throws ValidationException { + Long requesterId = req.getUserId(); + if (requesterId != null && !userHasRole(requesterId, roleForVerification)) { + log.trace("User {} has no role to allow this action", requesterId); + throw new ValidationException(roleVerificationError); + } else { + log.trace("Request without userId"); + } } - public boolean userHasRole(Long userId, Long companyId, IEnumKey role) { - return userHasRole(userId, companyId, role == null ? null : role.getKey()); + public RequestInfoUpdate validateRoleAndGetResult(BaseRequest req) { + Long requesterId = req.getUserId(); + if (requesterId != null && !userHasRole(requesterId, roleForVerification)) { + log.trace("User {} has no role to allow this action", requesterId); + return new RequestInfoUpdate() + .setId(req.getId()) + .setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error) + .setMessage("User (id %d) has no role to allow this action".formatted(requesterId)); + } else { + log.trace("Request without userId"); + } + return null; } - public boolean userHasRoleOnObject(Long userId, BusinessObject /*todo WithUserId / WithCompany */ bObject) { - //todo impl - return true; - } +// public UserRoleVerification(ImdgProvider imdg, UserRole roleForVerification, IErrorEnumId roleVerificationError) { +// userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); +// companyRoleSet = imdg.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); +// this.roleForVerification = roleForVerification; +// this.roleVerificationError = roleVerificationError; +// } +// protected Imdg companyRoleSet; +// protected Imdg users; +// +// public boolean userHasRole(Long userId, Long companyId, String userRole) { +// String query = String.format("userId=%s and companyId=%s and userRole=%s and status=%s", +// userId, companyId, userRole, Status.Active.getKey()); +// Collection roles = userRoleSessions.getCollectionIdsBySQL(query); +// log.trace("userHasRole: found {} roles by query: {}", roles.size(), query); +// return !roles.isEmpty(); +// } + + // userIsEnabled & exist - frontend-api validation - public boolean companyHasRole(Long companyId, String companyRole) { - String query = String.format("companyId=%s and companyRole=%s and workflowStatus=%s", - companyId, companyRole, Status.Active.getKey()); - Collection roles = companyRoleSet.getCollectionIdsBySQL(query); - log.trace("companyHasRole: found {} roles by query: {}", roles.size(), query); +// public boolean userHasRole(Long userId, Long companyId, IEnumKey role) { +// return userHasRole(userId, companyId, role == null ? null : role.getKey()); +// } + +// public boolean userHasRoleOnObject(Long userId, BusinessObject /*todo WithUserId / WithCompany */ bObject) { +// todo impl +// return true; +// } + + +// public boolean companyHasRole(Long companyId, String companyRole) { +// String query = String.format("companyId=%s and companyRole=%s and workflowStatus=%s", +// companyId, companyRole, Status.Active.getKey()); +// Collection roles = companyRoleSet.getCollectionIdsBySQL(query); +// log.trace("companyHasRole: found {} roles by query: {}", roles.size(), query); // if (roles.isEmpty()) return false; - //todo impl - return true; - } - - // userIsEnabled & exist - frontendapi validation + //todo impl +// return true; +// } } From cff4302c4af3509bee871cd59d45566717fadbdb Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 7 Apr 2023 12:46:26 +0300 Subject: [PATCH 81/90] UserRoleVerification modification 2 --- .../company/config/BeanConfiguration.java | 8 ++++++++ .../company/service/CompanyInfoService.java | 4 ++-- .../service/CompanyRoleSetService.java | 6 +++--- .../company/service/CompanyService.java | 4 ++-- .../util/security/UserRoleVerification.java | 19 +++++++++++++++---- 5 files changed, 30 insertions(+), 11 deletions(-) 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 3bb06b41e..18f1e518c 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 @@ -4,7 +4,11 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; +import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.platform.enumeration.UserRole; +import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; @@ -21,4 +25,8 @@ public class BeanConfiguration { return new RequestHelper(messageResolver); } + @Bean + public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver messageResolver) { + return new UserRoleVerification(imdgProvider, messageResolver, UserRole.Admin, CompanyErrors.UserVerifyDenial); + } } 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 c23d47b1e..6fad333bf 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 @@ -20,7 +20,6 @@ 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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.validation.IValidator; @@ -42,13 +41,14 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea public CompanyInfoService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, CompanyService companyService, RequestHelper requestHelper, ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, @Qualifier("CompanyInfoUpdateRequestValidator") Function companyInfoUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); this.companyService = companyService; this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.validationHelper = validationHelper; - this.userRoleVerification = new UserRoleVerification(imdgProvider, UserRole.Admin, CompanyErrors.UserVerifyDenial); + this.userRoleVerification = userRoleVerification; this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator; this.requestHelper = requestHelper.setLogger(log); } 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 e1b428cce..2a1b37691 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 @@ -19,7 +19,6 @@ 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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -48,7 +47,8 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing public CompanyRoleSetService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, RequestHelper requestHelper, - ValidationHelper validationHelper + ValidationHelper validationHelper, + UserRoleVerification userRoleVerification // @Qualifier("CompanyRoleSetRequestValidator") // Function companyNewRequestValidator, ) { @@ -56,7 +56,7 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing this.imdgProvider = imdgProvider; this.companyRoleSetMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = new UserRoleVerification(imdgProvider, UserRole.Admin, CompanyErrors.UserVerifyDenial); + this.userRoleVerification = userRoleVerification; this.validationHelper = validationHelper; // this.companyDeleteRequestValidator = companyDeleteRequestValidator; this.requestHelper = requestHelper.setLogger(log); 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 a7cec33f1..083eefcb8 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 @@ -22,7 +22,6 @@ 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.CompanySymbol; -import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; @@ -62,6 +61,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { ImdgProvider imdgProvider, RequestHelper requestHelper, ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, @Qualifier("companyNewRequestValidator") Function companyNewRequestValidator, @Qualifier("companyUpdateRequestValidator") @@ -79,7 +79,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = new UserRoleVerification(imdgProvider, UserRole.Admin, CompanyErrors.UserVerifyDenial); + this.userRoleVerification = userRoleVerification; this.validationHelper = validationHelper; this.companyNewRequestValidator = companyNewRequestValidator; this.companyUpdateRequestValidator = companyUpdateRequestValidator; diff --git a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java index 9cefe8add..b93c7ca27 100644 --- a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -10,11 +10,14 @@ import ru.spcex.platform.enumeration.Status; import ru.spcex.platform.enumeration.UserRole; 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.IEnumKey; import ru.spcex.platform.utils.enumeration.IErrorEnumId; +import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ValidationException; import java.util.Collection; +import java.util.Objects; /** * Проверка дополнительных прав пользователя. @@ -27,9 +30,16 @@ public class UserRoleVerification { protected Imdg userRoleSessions; protected UserRole roleForVerification; protected IErrorEnumId roleVerificationError; + protected IMessageResolver messageResolver; - public UserRoleVerification(ImdgProvider imdg, UserRole roleForVerification, IErrorEnumId roleVerificationError) { + public UserRoleVerification(ImdgProvider imdg, + IMessageResolver messageResolver, + UserRole roleForVerification, + IErrorEnumId roleVerificationError) { + Objects.requireNonNull(roleForVerification); + Objects.requireNonNull(roleVerificationError); userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); + this.messageResolver = messageResolver; this.roleForVerification = roleForVerification; this.roleVerificationError = roleVerificationError; } @@ -60,13 +70,14 @@ public class UserRoleVerification { public RequestInfoUpdate validateRoleAndGetResult(BaseRequest req) { Long requesterId = req.getUserId(); if (requesterId != null && !userHasRole(requesterId, roleForVerification)) { - log.trace("User {} has no role to allow this action", requesterId); + log.debug("User {} has no role to allow this action", requesterId); + String errMsg = messageResolver.resolve(new EnumMessage(roleVerificationError, requesterId)); return new RequestInfoUpdate() .setId(req.getId()) .setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error) - .setMessage("User (id %d) has no role to allow this action".formatted(requesterId)); + .setMessage(errMsg); } else { - log.trace("Request without userId"); + log.debug("Request without userId"); } return null; } From 3280be88e272e1c16dca2b9420e0be8ccaf707a4 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 7 Apr 2023 12:55:41 +0300 Subject: [PATCH 82/90] UserRoleVerification modification 3 --- .../clearing/company/config/BeanConfiguration.java | 4 ++-- .../clearing/company/service/CompanyInfoService.java | 3 ++- .../company/service/CompanyRoleSetService.java | 3 ++- .../spcex/clearing/company/service/CompanyService.java | 3 ++- .../clearing/util/security/UserRoleVerification.java | 10 ++++++++-- 5 files changed, 16 insertions(+), 7 deletions(-) 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 18f1e518c..0062de6f3 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 @@ -7,7 +7,6 @@ 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.security.UserRoleVerification; -import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; @@ -26,7 +25,8 @@ public class BeanConfiguration { } @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver messageResolver) { - return new UserRoleVerification(imdgProvider, messageResolver, UserRole.Admin, CompanyErrors.UserVerifyDenial); + return new UserRoleVerification(imdgProvider, messageResolver, CompanyErrors.UserVerifyDenial); } } 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 6fad333bf..8fb9950b7 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 @@ -20,6 +20,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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.validation.IValidator; @@ -48,7 +49,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea this.companyService = companyService; this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.validationHelper = validationHelper; - this.userRoleVerification = userRoleVerification; + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator; this.requestHelper = requestHelper.setLogger(log); } 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 2a1b37691..085ba8243 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 @@ -19,6 +19,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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -56,7 +57,7 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing this.imdgProvider = imdgProvider; this.companyRoleSetMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = userRoleVerification; + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; // this.companyDeleteRequestValidator = companyDeleteRequestValidator; this.requestHelper = requestHelper.setLogger(log); 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 083eefcb8..ef454ec15 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 @@ -22,6 +22,7 @@ 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.CompanySymbol; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; @@ -79,7 +80,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = userRoleVerification; + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; this.companyNewRequestValidator = companyNewRequestValidator; this.companyUpdateRequestValidator = companyUpdateRequestValidator; diff --git a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java index b93c7ca27..b865f4b67 100644 --- a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -34,13 +34,12 @@ public class UserRoleVerification { public UserRoleVerification(ImdgProvider imdg, IMessageResolver messageResolver, - UserRole roleForVerification, IErrorEnumId roleVerificationError) { Objects.requireNonNull(roleForVerification); Objects.requireNonNull(roleVerificationError); + Objects.requireNonNull(messageResolver); userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); this.messageResolver = messageResolver; - this.roleForVerification = roleForVerification; this.roleVerificationError = roleVerificationError; } @@ -58,6 +57,7 @@ public class UserRoleVerification { public void validateRoleAndThrow(BaseRequest req) throws ValidationException { + Objects.requireNonNull(roleForVerification); Long requesterId = req.getUserId(); if (requesterId != null && !userHasRole(requesterId, roleForVerification)) { log.trace("User {} has no role to allow this action", requesterId); @@ -68,6 +68,7 @@ public class UserRoleVerification { } public RequestInfoUpdate validateRoleAndGetResult(BaseRequest req) { + Objects.requireNonNull(roleForVerification); Long requesterId = req.getUserId(); if (requesterId != null && !userHasRole(requesterId, roleForVerification)) { log.debug("User {} has no role to allow this action", requesterId); @@ -82,6 +83,11 @@ public class UserRoleVerification { return null; } + public UserRoleVerification setRoleForVerification(UserRole roleForVerification) { + this.roleForVerification = roleForVerification; + return this; + } + // public UserRoleVerification(ImdgProvider imdg, UserRole roleForVerification, IErrorEnumId roleVerificationError) { // userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); // companyRoleSet = imdg.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); From 2269f2c10e35f89d605febf069fe924f7feae771 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 7 Apr 2023 13:02:56 +0300 Subject: [PATCH 83/90] =?UTF-8?q?UserRoleVerification=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D0=B8=D0=B9=20=D0=B8=20=D0=BB=D0=BE=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spcex/clearing/util/security/UserRoleVerification.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java index b865f4b67..d1838aa96 100644 --- a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -21,8 +21,10 @@ import java.util.Objects; /** * Проверка дополнительных прав пользователя. - *

+ *

* Основная проверка прав осуществляется на frontend-api, и использовать этот компонент дополнительно не требуется. + *

+ * Использовать @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE), требует задание роли через setRoleForVerification(role) */ public class UserRoleVerification { protected Logger log = LoggerFactory.getLogger(getClass()); @@ -84,6 +86,7 @@ public class UserRoleVerification { } public UserRoleVerification setRoleForVerification(UserRole roleForVerification) { + log.debug("{} configure to check role {}", this, roleForVerification); this.roleForVerification = roleForVerification; return this; } From cb3b251ee5df2e5b2f1883fb9824082ae36f9d35 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 7 Apr 2023 13:50:06 +0300 Subject: [PATCH 84/90] UserRoleVerification for company-service --- .../validation/common/ValidationHelper.java | 2 ++ .../company/config/BeanConfiguration.java | 3 ++- .../ClearingMemberCategoryService.java | 19 ++++++++++--- .../company/service/CompanyInfoService.java | 3 +-- .../service/CompanyRoleSetService.java | 9 ++++--- .../company/service/CompanyService.java | 27 +++++++++++-------- .../company/service/ContactService.java | 18 ++++++++----- .../service/ProfileDocumentService.java | 17 +++++++++--- .../util/security/UserRoleVerification.java | 17 +++++++++++- 9 files changed, 83 insertions(+), 32 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java index d8024bc4e..9a3ad0c24 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java @@ -9,6 +9,7 @@ import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; +import java.util.Objects; import java.util.Optional; import java.util.function.Function; @@ -18,6 +19,7 @@ public class ValidationHelper { private IMessageResolver messageResolver; public ValidationHelper(IMessageResolver messageResolver) { + Objects.requireNonNull(messageResolver); this.messageResolver = messageResolver; } 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 0062de6f3..d0189af7a 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 @@ -7,6 +7,7 @@ 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.security.UserRoleVerification; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; @@ -27,6 +28,6 @@ public class BeanConfiguration { @Bean @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver messageResolver) { - return new UserRoleVerification(imdgProvider, messageResolver, CompanyErrors.UserVerifyDenial); + return new UserRoleVerification(imdgProvider, messageResolver, UserRole.Admin, CompanyErrors.UserVerifyDenial); } } 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 56c7335ad..b777d0a1e 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 @@ -17,6 +17,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCat import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; 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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -33,12 +34,14 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private final Function clearingMemberCategoryUpdateRequestValidator; private final Function clearingMemberCategoryDeleteRequestValidator; private final ValidationHelper validationHelper; + private final UserRoleVerification userRoleVerification; @Autowired public ClearingMemberCategoryService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, @Qualifier("clearingMemberCategoryNewRequestValidator") Function clearingMemberCategoryNewRequestValidator, @Qualifier("clearingMemberCategoryUpdateRequestValidator") Function clearingMemberCategoryUpdateRequestValidator, @Qualifier("clearingMemberCategoryDeleteRequestValidator") Function clearingMemberCategoryDeleteRequestValidator) { @@ -48,6 +51,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init this.clearingMemberCategoryUpdateRequestValidator = clearingMemberCategoryUpdateRequestValidator; this.clearingMemberCategoryDeleteRequestValidator = clearingMemberCategoryDeleteRequestValidator; this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; } @Override @@ -67,7 +71,10 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { log.debug("ClearingMemberCategoryNewRequest received {}", userRequest.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryNewRequestValidator); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryNewRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); @@ -84,7 +91,10 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init public RequestInfoUpdate clearingMemberCategoryUpdate(BaseRequest userRequest) { ClearingMemberCategoryUpdateRequest req = userRequest.getRequestPayload(); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryUpdateRequestValidator); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryUpdateRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("ClearingMemberCategoryUpdateRequest received"); @@ -100,7 +110,10 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private RequestInfoUpdate clearingMemberCategoryDelete(BaseRequest userRequest) { CommonDeleteRequest req = userRequest.getRequestPayload(); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryDeleteRequestValidator); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryDeleteRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; log.debug("CommonDeleteRequest received id = {}", req.getId()); 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 8fb9950b7..6fad333bf 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 @@ -20,7 +20,6 @@ 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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.validation.IValidator; @@ -49,7 +48,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea this.companyService = companyService; this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.validationHelper = validationHelper; - this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); + this.userRoleVerification = userRoleVerification; this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator; this.requestHelper = requestHelper.setLogger(log); } 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 085ba8243..2af7a358c 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 @@ -19,7 +19,6 @@ 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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -57,7 +56,7 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing this.imdgProvider = imdgProvider; this.companyRoleSetMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); + this.userRoleVerification = userRoleVerification; this.validationHelper = validationHelper; // this.companyDeleteRequestValidator = companyDeleteRequestValidator; this.requestHelper = requestHelper.setLogger(log); @@ -82,7 +81,8 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing CompanyRoleSetNewRequest req = companyRoleNewRequestBaseRequest.getRequestPayload(); log.debug("companyroleset-new request received, BaseRequest.id = {}", companyRoleNewRequestBaseRequest.getId()); { // Валидация, ValidationException - userRoleVerification.validateRoleAndThrow(companyRoleNewRequestBaseRequest); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyRoleNewRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; // RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyRoleNewRequestBaseRequest, companyNewRequestValidator); // if (requestInfoUpdate != null) return requestInfoUpdate; } @@ -118,7 +118,8 @@ public class CompanyRoleSetService extends QueueConsumer implements Initializing CommonDeleteRequest request = companyRoleSetDeleteRequest.getRequestPayload(); log.debug("companyRoleSetDeleteRequest received id = {}", request.getId()); { // Валидация, ValidationException - userRoleVerification.validateRoleAndThrow(companyRoleSetDeleteRequest); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyRoleSetDeleteRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; if (request.getId() == null) { return requestHelper.makeErrorResponse(companyRoleSetDeleteRequest, CompanyErrors.RequiredFieldEmpty, "id"); } 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 ef454ec15..3fc6f9a6e 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 @@ -22,7 +22,6 @@ 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.CompanySymbol; -import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; @@ -80,7 +79,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); + this.userRoleVerification = userRoleVerification; this.validationHelper = validationHelper; this.companyNewRequestValidator = companyNewRequestValidator; this.companyUpdateRequestValidator = companyUpdateRequestValidator; @@ -107,9 +106,11 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private synchronized RequestInfoUpdate createCompany(BaseRequest companyNewRequestBaseRequest) throws ValidationException { CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); - { // Валидация, ValidationException - userRoleVerification.validateRoleAndThrow(companyNewRequestBaseRequest); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyNewRequestBaseRequest, companyNewRequestValidator); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyNewRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(companyNewRequestBaseRequest, companyNewRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } Company company = new Company(); @@ -153,9 +154,11 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private synchronized RequestInfoUpdate updateCompany(BaseRequest companyUpdateRequestBaseRequest) throws ValidationException { CompanyNewRequest updateRequest = companyUpdateRequestBaseRequest.getRequestPayload(); - { // Валидация, ValidationException - userRoleVerification.validateRoleAndThrow(companyUpdateRequestBaseRequest); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyUpdateRequestBaseRequest, companyUpdateRequestValidator); + { // Валидация, + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyUpdateRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(companyUpdateRequestBaseRequest, companyUpdateRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } ImdgTransaction transaction = imdgProvider.newTransaction(); @@ -234,9 +237,11 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private synchronized RequestInfoUpdate deleteCompany(BaseRequest companyBlockRequestBaseRequest) throws ValidationException { CommonDeleteRequest request = companyBlockRequestBaseRequest.getRequestPayload(); log.debug("CommonDeleteRequest (block request) received id = {}", request.getId()); - { // Валидация, ValidationException - userRoleVerification.validateRoleAndThrow(companyBlockRequestBaseRequest); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(companyBlockRequestBaseRequest, companyDeleteRequestValidator); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyBlockRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(companyBlockRequestBaseRequest, companyDeleteRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; } ImdgTransaction transaction = imdgProvider.newTransaction(); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java index 814902983..986806075 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ContactService.java @@ -16,6 +16,7 @@ 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.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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -30,17 +31,20 @@ public class ContactService extends QueueConsumer implements InitializingBean { private final ValidationHelper validationHelper; private final Function contactNewRequestValidator; private final Function contactUpdateRequestValidator; + private final UserRoleVerification userRoleVerification; @Autowired public ContactService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, @Qualifier("contactNewRequestValidator") Function contactNewRequestValidator, @Qualifier("contactUpdateRequestValidator") Function contactUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); this.contactMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Contact, Contact.class); this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; this.contactNewRequestValidator = contactNewRequestValidator; this.contactUpdateRequestValidator = contactUpdateRequestValidator; } @@ -59,9 +63,10 @@ public class ContactService extends QueueConsumer implements InitializingBean { public RequestInfoUpdate contactNew(BaseRequest userRequest) { log.debug("ContactNewRequest received"); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( - userRequest, contactNewRequestValidator - ); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, contactNewRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; ContactNewRequest contactNewRequest = userRequest.getRequestPayload(); @@ -78,9 +83,10 @@ public class ContactService extends QueueConsumer implements InitializingBean { public RequestInfoUpdate contactUpdate(BaseRequest userRequest) { log.debug("ContactUpdateRequest received"); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( - userRequest, contactUpdateRequestValidator - ); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, contactUpdateRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; // Тип контакта не меняем, при валидации кидаем ошибку. 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 8204af83a..b8f9bbdbd 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 @@ -19,6 +19,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUp 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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -37,12 +38,14 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin private final Function profileDocumentNewRequestValidator; private final Function profileDocumentUpdateRequestValidator; private final ValidationHelper validationHelper; + private final UserRoleVerification userRoleVerification; @Autowired public ProfileDocumentService(Consumer kafkaQueue, Producer kafkaProducer, KafkaSender kafkaReqProducer, ImdgProvider imdgProvider, + UserRoleVerification userRoleVerification, @Qualifier("profileDocumentNewRequestValidation") Function profileDocumentNewRequestValidator, @Qualifier("profileDocumentUpdateRequestValidation") Function profileDocumentUpdateRequestValidator, ValidationHelper validationHelper) { @@ -52,6 +55,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin this.profileDocumentNewRequestValidator = profileDocumentNewRequestValidator; this.profileDocumentUpdateRequestValidator = profileDocumentUpdateRequestValidator; this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; } @Override @@ -72,9 +76,11 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin private RequestInfoUpdate profileDocumentNew(BaseRequest profileDocumentNewRequestBaseRequest) { log.trace("Start processing ProfileDocumentNewRequest!"); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( - profileDocumentNewRequestBaseRequest, - profileDocumentNewRequestValidator + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentNewRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError( + profileDocumentNewRequestBaseRequest, profileDocumentNewRequestValidator ); if (requestInfoUpdate != null) return requestInfoUpdate; @@ -106,7 +112,10 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin private RequestInfoUpdate profileDocumentUpdate(BaseRequest profileDocumentUpdateRequestBaseRequest) { log.trace("Start processing ProfileDocumentUpdateRequest!"); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError( + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentUpdateRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError( profileDocumentUpdateRequestBaseRequest, profileDocumentUpdateRequestValidator ); diff --git a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java index d1838aa96..7c1911380 100644 --- a/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -24,7 +24,8 @@ import java.util.Objects; *

* Основная проверка прав осуществляется на frontend-api, и использовать этот компонент дополнительно не требуется. *

- * Использовать @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE), требует задание роли через setRoleForVerification(role) + * Использовать @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE), требует задание роли через setRoleForVerification(role). + * Либо роль можно задать во втором конструкторе, переопределив её где требуется (если используется scope prototype) */ public class UserRoleVerification { protected Logger log = LoggerFactory.getLogger(getClass()); @@ -45,6 +46,20 @@ public class UserRoleVerification { this.roleVerificationError = roleVerificationError; } + public UserRoleVerification(ImdgProvider imdg, + IMessageResolver messageResolver, + UserRole roleForVerification, + IErrorEnumId roleVerificationError) { + Objects.requireNonNull(roleForVerification); + Objects.requireNonNull(roleVerificationError); + Objects.requireNonNull(messageResolver); + Objects.requireNonNull(roleForVerification); + userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); + this.messageResolver = messageResolver; + this.roleVerificationError = roleVerificationError; + this.roleForVerification = roleForVerification; + } + protected boolean userHasRole(Long userId, IEnumKey role) { return userHasRole(userId, role == null ? null : role.getKey()); } From b0e7595d7323d0d604e8fc44eaca17317d4e8c77 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Fri, 7 Apr 2023 14:19:59 +0300 Subject: [PATCH 85/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83=20=D1=80=D0=BE=D0=BB=D0=B5?= =?UTF-8?q?=D0=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clearing-parent/securities-service/pom.xml | 4 ++++ .../securities/config/ValidationConfig.java | 11 +++++++++++ .../securities/errors/SecuritiesError.java | 1 + .../service/cud/CouponPeriodService.java | 10 +++++++++- .../securities/service/cud/CurrencyService.java | 10 +++++++++- .../service/cud/EquitySecurityService.java | 15 +++++++++++++-- .../service/cud/FixedIncomeCashFlowService.java | 10 +++++++++- .../service/cud/FixedIncomeSecurityService.java | 15 +++++++++++++-- .../service/cud/MoneyMarketSecurityService.java | 14 ++++++++++++++ 9 files changed, 83 insertions(+), 7 deletions(-) diff --git a/clearing-parent/securities-service/pom.xml b/clearing-parent/securities-service/pom.xml index ae27be76c..e838f0eec 100644 --- a/clearing-parent/securities-service/pom.xml +++ b/clearing-parent/securities-service/pom.xml @@ -50,6 +50,10 @@ spring-boot-starter-test test + + ru.spcex.clearing + security-util + diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java index 6fcd1fcf6..4d1263bc2 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java @@ -1,11 +1,16 @@ package ru.spcex.clearing.securities.config; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; import ru.clearing.platform.dictionary.CountryCodeDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.securities.errors.SecuritiesError; +import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IMessageResolver; @@ -29,8 +34,14 @@ public class ValidationConfig { } @Bean("validationHelper") + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public ValidationHelper validationHelper(IMessageResolver messageResolver) { return new ValidationHelper(messageResolver); } + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public UserRoleVerification userRoleVerification(ImdgProvider imdgProvider, IMessageResolver messageResolver) { + return new UserRoleVerification(imdgProvider, messageResolver, UserRole.Admin, SecuritiesError.UserVerifyDenial); + } } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java index 5a64dc08e..40d4e0641 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java @@ -3,6 +3,7 @@ package ru.spcex.clearing.securities.errors; import ru.spcex.platform.utils.enumeration.IErrorEnumId; public enum SecuritiesError implements IErrorEnumId { + UserVerifyDenial(1001L), // 'Нет прав на проведение данной операции RequiredFieldIsEmpty(1002L), WrongFieldValue(1004L), InstrumentAlreadyExists(1010L), diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java index e6bf52ebe..d99d1e678 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java @@ -16,7 +16,9 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodU import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -29,18 +31,21 @@ public class CouponPeriodService extends QueueConsumer implements InitializingBe private final ImdgId idGenerator; private final ValidationProvider validation; private final ValidationHelper validationHelper; + private final UserRoleVerification userRoleVerification; @Autowired public CouponPeriodService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, ValidationProvider validation, + UserRoleVerification userRoleVerification, ValidationHelper validationHelper) { super(kafkaQueue, kafkaProducer); this.validation = validation; this.couponPeriodImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CouponPeriod, CouponPeriod.class); this.imdgProvider = imdgProvider; this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; } @@ -79,7 +84,10 @@ public class CouponPeriodService extends QueueConsumer implements InitializingBe CouponPeriodUpdateRequest req = userRequest.getRequestPayload(); log.debug("updateCurrency received id = {}", req.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.couponPeriodUpdateValidator()); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.couponPeriodUpdateValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; CouponPeriod couponPeriod = couponPeriodImdg.getSingleObjectByID(req.getId()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java index 8796e8e76..9ad133b26 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java @@ -16,7 +16,9 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyUpdat import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -28,6 +30,7 @@ public class CurrencyService extends QueueConsumer implements InitializingBean { private final ImdgProvider imdgProvider; private final ImdgId idGenerator; private final ValidationProvider validation; + private final UserRoleVerification userRoleVerification; private final ValidationHelper validationHelper; @Autowired @@ -35,12 +38,14 @@ public class CurrencyService extends QueueConsumer implements InitializingBean { Producer kafkaProducer, ImdgProvider imdgProvider, ValidationProvider validation, + UserRoleVerification userRoleVerification, ValidationHelper validationHelper) { super(kafkaQueue, kafkaProducer); this.validation = validation; this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class); this.imdgProvider = imdgProvider; this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; } @@ -76,7 +81,10 @@ public class CurrencyService extends QueueConsumer implements InitializingBean { CurrencyUpdateRequest req = userRequest.getRequestPayload(); log.debug("updateCurrency received id = {}", req.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.currencyUpdateValidator()); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.currencyUpdateValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; Currency currency = currencyImdg.getSingleObjectByID(req.getId()); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java index 5a3585bb8..c19885ee4 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java @@ -19,7 +19,9 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -36,6 +38,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing private final ImdgProvider imdgProvider; private final ImdgId idGenerator; private final ValidationProvider validation; + private final UserRoleVerification userRoleVerification; private final ValidationHelper validationHelper; private final ListingBuilder listingBuilder = new ListingBuilder(); @@ -43,6 +46,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing public EquitySecurityService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, + UserRoleVerification userRoleVerification, ValidationProvider validation, ValidationHelper validationHelper) { super(kafkaQueue, kafkaProducer); @@ -51,6 +55,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); this.imdgProvider = imdgProvider; this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; } @@ -116,7 +121,10 @@ public class EquitySecurityService extends QueueConsumer implements Initializing EquitySecurityUpdateRequest req = userRequest.getRequestPayload(); log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityUpdateValidator()); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityUpdateValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; EquitySecurity equity = equitySecurityImdg.getSingleObjectByID(req.getId()); @@ -149,7 +157,10 @@ public class EquitySecurityService extends QueueConsumer implements Initializing CommonDeleteRequest req = userRequest.getRequestPayload(); log.debug("CommonDeleteRequest received id = {}", req.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityDeleteValidator()); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.equityDeleteValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; Instant updateTime = Instant.now(); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java index ab17cf7ed..6b99a0c32 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java @@ -15,7 +15,9 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCa import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowUpdateRequest; 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.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.validation.IValidator; @@ -27,6 +29,7 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg fixedIncomeCashFlowImdg; private final ImdgProvider imdgProvider; + private final UserRoleVerification userRoleVerification; private final ValidationHelper validationHelper; private final Function fixedIncomeCashFlowNewRequestValidator; @@ -35,11 +38,13 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial public FixedIncomeCashFlowService(Consumer kafkaQueue, Producer kafkaResponseQueue, ImdgProvider imdgProvider, + UserRoleVerification userRoleVerification, ValidationHelper validationHelper, @Qualifier("fixedIncomeCashFlowNewRequestValidator") Function fixedIncomeCashFlowNewRequestValidator, @Qualifier("fixedIncomeCashFlowUpdateRequestValidator") Function fixedIncomeCashFlowUpdateRequestValidator) { super(kafkaQueue, kafkaResponseQueue); this.imdgProvider = imdgProvider; + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; this.fixedIncomeCashFlowNewRequestValidator = fixedIncomeCashFlowNewRequestValidator; this.fixedIncomeCashFlowUpdateRequestValidator = fixedIncomeCashFlowUpdateRequestValidator; @@ -83,7 +88,10 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial public RequestInfoUpdate fixedIncomeCashFlowUpdate(BaseRequest userRequest) { log.debug("FixedIncomeCashFlowUpdateRequest received {}", userRequest.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, fixedIncomeCashFlowUpdateRequestValidator); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, fixedIncomeCashFlowUpdateRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; FixedIncomeCashFlowUpdateRequest req = userRequest.getRequestPayload(); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java index aa618aefa..d571ed199 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java @@ -19,7 +19,9 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -36,6 +38,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial private final ImdgProvider imdgProvider; private final ImdgId idGenerator; private final ValidationProvider validation; + private final UserRoleVerification userRoleVerification; private final ValidationHelper validationHelper; private final ListingBuilder listingBuilder = new ListingBuilder(); @@ -44,6 +47,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial Producer kafkaProducer, ImdgProvider imdgProvider, ValidationProvider validation, + UserRoleVerification userRoleVerification, ValidationHelper validationHelper) { super(kafkaQueue, kafkaProducer); this.validation = validation; @@ -51,6 +55,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); this.imdgProvider = imdgProvider; this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; } @@ -121,7 +126,10 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial FixedIncomeSecurityUpdateRequest req = userRequest.getRequestPayload(); log.debug("updateFixedIncome received id = {}", req.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeUpdateValidator()); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeUpdateValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; FixedIncomeSecurity fixedIncome = fixedIncomeSecurityImdg.getSingleObjectByID(req.getId()); @@ -160,7 +168,10 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial CommonDeleteRequest req = userRequest.getRequestPayload(); log.debug("CommonDeleteRequest received id = {}", req.getId()); - RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeDeleteValidator()); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeDeleteValidator()); if (requestInfoUpdate != null) return requestInfoUpdate; Instant updateTime = Instant.now(); diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java index c96cb0e94..55c1c14b5 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java @@ -21,7 +21,9 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.validation.ValidationProvider; +import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -43,6 +45,7 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial private final ImdgProvider imdgProvider; private final ImdgId idGenerator; private final ValidationProvider validation; + private final UserRoleVerification userRoleVerification; private final ValidationHelper validationHelper; private final IMessageResolver messageResolver; private final ListingBuilder listingBuilder = new ListingBuilder(); @@ -52,9 +55,11 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial Producer kafkaProducer, ImdgProvider imdgProvider, ValidationProvider validation, + UserRoleVerification userRoleVerification, ValidationHelper validationHelper, IMessageResolver messageResolver) { super(kafkaQueue, kafkaProducer); + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; this.validation = validation; this.moneyMarketSecurityMap = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class); @@ -145,6 +150,10 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial private RequestInfoUpdate updateMoneyMarket(BaseRequest userRequest) { MoneyMarketSecurityUpdateRequest req = userRequest.getRequestPayload(); log.debug("MoneyMarketSecurityUpdateRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + IValidator validator = validation.mmsUpdateValidator().apply(req); Optional validationError = validator.tillFirstError(); if (validationError.isPresent()) { @@ -190,6 +199,11 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial private RequestInfoUpdate deleteMoneyMarket(BaseRequest userRequest) { CommonDeleteRequest req = userRequest.getRequestPayload(); log.debug("CommonDeleteRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + IValidator validator = validation.mmsDeleteValidator().apply(req); Optional validationError = validator.tillFirstError(); if (validationError.isPresent()) { From 5aea636e352ea41bc9cf054198f631b648ce193a Mon Sep 17 00:00:00 2001 From: psemenkov Date: Fri, 7 Apr 2023 17:09:20 +0300 Subject: [PATCH 86/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B5=20=D1=83=D1=82=D0=B8=D0=BB?= =?UTF-8?q?=D0=B8=D1=82=D1=8B=20=D0=B2=20test-clearing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../queue/AbstractControllerTest.java | 10 +- clearing-parent/securities-service/pom.xml | 5 + .../service/cud/CouponPeriodService.java | 3 +- .../service/AbstractServiceTest.java | 6 +- .../service/CouponPeriodServiceTest.java | 6 +- .../service/CurrencyServiceTest.java | 7 +- .../service/EquitySecurityServiceTest.java | 6 +- .../FixedIncomeCashFlowServiceTest.java | 8 +- .../FixedIncomeSecurityServiceTest.java | 6 +- .../MoneyMarketSecurityServiceTest.java | 6 +- clearing-parent/test-clearing/pom.xml | 36 ++----- .../ru/spcex/clearing}/MatcherFactory.java | 4 +- .../java/ru/spcex/clearing}/TestUtils.java | 29 +++++- ...yImdg.java => MatcherFactoryWithJson.java} | 12 +-- .../ru/spcex/clearing/imdg/TestUtils.java | 95 ------------------- 15 files changed, 76 insertions(+), 163 deletions(-) rename clearing-parent/{securities-service/src/test/java/ru/spcex/clearing/securities/utils => test-clearing/src/main/java/ru/spcex/clearing}/MatcherFactory.java (96%) rename clearing-parent/{securities-service/src/test/java/ru/spcex/clearing/securities/utils => test-clearing/src/main/java/ru/spcex/clearing}/TestUtils.java (75%) rename clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/{MatcherFactoryImdg.java => MatcherFactoryWithJson.java} (84%) delete mode 100644 clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/TestUtils.java diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java index d210e7118..6e0cf32b8 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java @@ -27,6 +27,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import ru.clearing.classes.statics.data.user.User; +import ru.spcex.clearing.TestUtils; import ru.spcex.clearing.backendapi.controller.config.*; import ru.spcex.clearing.backendapi.controller.queue.account.AccountBalanceController; import ru.spcex.clearing.backendapi.controller.queue.account.AccountController; @@ -58,8 +59,7 @@ import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllRespo import ru.spcex.clearing.backendapi.domain.actions.IAction; import ru.spcex.clearing.backendapi.meta.GetResponseFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.imdg.MatcherFactoryImdg; -import ru.spcex.clearing.imdg.TestUtils; +import ru.spcex.clearing.imdg.MatcherFactoryWithJson; import ru.spcex.clearing.platform.messaging.domain.ActionType; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -82,7 +82,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static ru.spcex.clearing.imdg.JsonUtil.readValue; import static ru.spcex.clearing.imdg.JsonUtil.writeValue; -import static ru.spcex.clearing.imdg.MatcherFactoryImdg.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.imdg.MatcherFactoryWithJson.usingIgnoringFieldsComparatorForClass; @ContextConfiguration(classes = { @@ -156,8 +156,8 @@ import static ru.spcex.clearing.imdg.MatcherFactoryImdg.usingIgnoringFieldsCompa @WebMvcTest//(controllers = DeleteCompanyController.class) //@TestPropertySource(properties = "spring.config.location=D:/repo/mfd/clearing/clearing-parent/backend-api/src/main/resources/") public abstract class AbstractControllerTest { - protected static final MatcherFactoryImdg.Matcher BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(BaseRequest.class); - protected static final MatcherFactoryImdg.Matcher CUD_RESPONSE_MATCHER = usingIgnoringFieldsComparator(CudResponse.class); + protected static final MatcherFactoryWithJson.Matcher BASE_REQUEST_MATCHER = usingIgnoringFieldsComparatorForClass(BaseRequest.class); + protected static final MatcherFactoryWithJson.Matcher CUD_RESPONSE_MATCHER = usingIgnoringFieldsComparatorForClass(CudResponse.class); protected static final AtomicLong currentId = new AtomicLong(); private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter(); diff --git a/clearing-parent/securities-service/pom.xml b/clearing-parent/securities-service/pom.xml index e838f0eec..29185becc 100644 --- a/clearing-parent/securities-service/pom.xml +++ b/clearing-parent/securities-service/pom.xml @@ -45,6 +45,11 @@ jackson-databind + + ru.spcex.clearing + test-clearing + test + org.springframework.boot spring-boot-starter-test diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java index d99d1e678..cae5e69ab 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java @@ -18,7 +18,6 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.securities.validation.ValidationProvider; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; -import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -45,7 +44,7 @@ public class CouponPeriodService extends QueueConsumer implements InitializingBe this.couponPeriodImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CouponPeriod, CouponPeriod.class); this.imdgProvider = imdgProvider; this.idGenerator = imdgProvider.getImdgIdGenerator(); - this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); + this.userRoleVerification = userRoleVerification; this.validationHelper = validationHelper; } diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java index e83f7f6cd..98547e2bb 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -18,6 +18,8 @@ import ru.clearing.classes.statics.data.misc.Currency; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; import ru.clearing.platform.dictionary.*; +import ru.spcex.clearing.MatcherFactory; +import ru.spcex.clearing.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.config.ErrorResolverConfig; @@ -25,8 +27,6 @@ import ru.spcex.clearing.securities.config.ImdgTestConfig; import ru.spcex.clearing.securities.config.KafkaTestConfig; import ru.spcex.clearing.securities.config.ValidationConfig; import ru.spcex.clearing.securities.service.cud.*; -import ru.spcex.clearing.securities.utils.MatcherFactory; -import ru.spcex.clearing.securities.utils.TestUtils; import ru.spcex.clearing.securities.validation.ValidationProvider; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -35,7 +35,7 @@ import java.util.concurrent.atomic.AtomicLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java index c6cc8c02b..b1d750ea4 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java @@ -4,19 +4,19 @@ import org.apache.kafka.clients.consumer.MockConsumer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.CouponPeriod; +import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodUpdateRequest; import ru.spcex.clearing.securities.service.cud.CouponPeriodService; -import ru.spcex.clearing.securities.utils.MatcherFactory; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.time.LocalDate; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.securities.utils.TestUtils.*; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.TestUtils.*; public class CouponPeriodServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher COUPON_PERIOD_MATCHER = usingIgnoringFieldsComparator(); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java index 525074512..ec5ff1721 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java @@ -4,17 +4,18 @@ import org.apache.kafka.clients.consumer.MockConsumer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.misc.Currency; +import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyUpdateRequest; import ru.spcex.clearing.securities.service.cud.CurrencyService; -import ru.spcex.clearing.securities.utils.MatcherFactory; import javax.annotation.PostConstruct; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.securities.utils.TestUtils.*; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.TestUtils.*; + public class CurrencyServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher CURRENCY_MATCHER = usingIgnoringFieldsComparator(); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java index ffd9b4355..05d03bd67 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java @@ -5,20 +5,20 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.misc.Listing; +import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; import ru.spcex.clearing.securities.service.cud.EquitySecurityService; -import ru.spcex.clearing.securities.utils.MatcherFactory; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.util.Map; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.securities.utils.TestUtils.*; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.TestUtils.*; public class EquitySecurityServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher EQUITY_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java index 18214b4a2..7f7ee673d 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java @@ -13,6 +13,7 @@ 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.instrument.issue.FixedIncomeCashFlow; +import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowNewRequest; @@ -23,7 +24,6 @@ import ru.spcex.clearing.securities.config.KafkaTestConfig; import ru.spcex.clearing.securities.config.ValidationConfig; import ru.spcex.clearing.securities.config.validation.FixedIncomeCashFlowValidationConfig; import ru.spcex.clearing.securities.service.cud.FixedIncomeCashFlowService; -import ru.spcex.clearing.securities.utils.MatcherFactory.Matcher; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -31,9 +31,9 @@ import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.time.LocalDate; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.TestUtils.*; import static ru.spcex.clearing.securities.config.ImdgTestConfig.currentID; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.securities.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { @@ -44,7 +44,7 @@ import static ru.spcex.clearing.securities.utils.TestUtils.*; KafkaTestConfig.class, ImdgTestConfig.class}) class FixedIncomeCashFlowServiceTest { - public static final Matcher FIXED_INCOME_CASH_FLOW_MATCHER = usingIgnoringFieldsComparator(); + public static final MatcherFactory.Matcher FIXED_INCOME_CASH_FLOW_MATCHER = usingIgnoringFieldsComparator(); private static final String TOPIC_FIXED_INCOME_CASH_FLOW_NEW = Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_NEW; private static final String TOPIC_FIXED_INCOME_CASH_FLOW_UPDATE = Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_UPDATE; diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java index 818633338..8470d6a23 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java @@ -5,21 +5,21 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Listing; +import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityUpdateRequest; import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; -import ru.spcex.clearing.securities.utils.MatcherFactory; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.time.LocalDate; import java.util.Map; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.securities.utils.TestUtils.*; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.TestUtils.*; public class FixedIncomeSecurityServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher FIXED_INCOME_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java index e5ddda98b..e65e48a91 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; +import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -14,15 +15,14 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSe import ru.spcex.clearing.platform.messaging.service.RequestInfo; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; -import ru.spcex.clearing.securities.utils.MatcherFactory; import ru.spcex.platform.imdg.api.Imdg; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.util.Map; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.securities.utils.TestUtils.*; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.TestUtils.*; public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{ private static final MatcherFactory.Matcher MONEY_MARKET_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); diff --git a/clearing-parent/test-clearing/pom.xml b/clearing-parent/test-clearing/pom.xml index 6cd40dfc1..cae0c252e 100644 --- a/clearing-parent/test-clearing/pom.xml +++ b/clearing-parent/test-clearing/pom.xml @@ -8,11 +8,8 @@ test-clearing Test-clearing + SPCEX-1.0.0.0 - - org.springframework.boot - spring-boot-starter-web - ru.spcex.platform platform-imdg-api @@ -21,6 +18,10 @@ ru.spcex.platform platform-messaging + + org.springframework.boot + spring-boot-starter-web + com.fasterxml.jackson.core jackson-databind @@ -28,50 +29,27 @@ org.springframework spring-test - test org.skyscreamer jsonassert - test - - - org.junit.jupiter - junit-jupiter - test org.assertj assertj-core - test org.reflections reflections 0.9.11 - - org.springframework.boot - spring-boot-test-autoconfigure - test - org.mockito mockito-core - org.springframework - spring-test - - - org.assertj - assertj-core - 3.23.1 - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 + org.junit.jupiter + junit-jupiter-api - SPCEX-1.0.0.0 diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/MatcherFactory.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/MatcherFactory.java similarity index 96% rename from clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/MatcherFactory.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/MatcherFactory.java index 63bd29dab..bf8c58af3 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/MatcherFactory.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/MatcherFactory.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.securities.utils; +package ru.spcex.clearing; import java.util.Arrays; @@ -35,4 +35,4 @@ public class MatcherFactory { assertThat(actual).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(expected); } } -} \ No newline at end of file +} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/TestUtils.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/TestUtils.java similarity index 75% rename from clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/TestUtils.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/TestUtils.java index c34e15531..e97deebb6 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/TestUtils.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/TestUtils.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.securities.utils; +package ru.spcex.clearing; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -13,12 +13,14 @@ 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.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -27,8 +29,8 @@ import java.util.concurrent.TimeoutException; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; +import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.platform.messaging.service.Status.Success; -import static ru.spcex.clearing.securities.utils.MatcherFactory.usingIgnoringFieldsComparator; public class TestUtils { public static final MatcherFactory.Matcher> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(); @@ -52,6 +54,29 @@ public class TestUtils { BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); } + public static void waitingWhenTryAddRecordAndCheckError(Long id, + MockProducer mockProducer, + ArgumentCaptor producerRecord, + String errorCode, + List errorMessageArgs) { + BaseRequest predictableBaseRequest = new BaseRequest<>(); + predictableBaseRequest.setId(id); + predictableBaseRequest.setActionType(ActionType.SYSTEM); + RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate(); + requestInfoUpdate.setId(id); + requestInfoUpdate.setStatus(Status.Error); + String errorsMessage = "(%s) args [%s]".formatted(errorCode, String.join(", ", errorMessageArgs)); + requestInfoUpdate.setMessage(errorsMessage); + predictableBaseRequest.setRequestPayload(requestInfoUpdate); + + //waiting for kafka producer send message (finale event) + verify(mockProducer, timeout(30_000L).times(1)) + .send(producerRecord.capture()); + + BaseRequest baseRequestResult = (BaseRequest) producerRecord.getValue().value(); + assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic()); + BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); + } public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) { TopicPartition tp = new TopicPartition(topic, partition); HashMap startOffsets = new HashMap<>(); diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryImdg.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryWithJson.java similarity index 84% rename from clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryImdg.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryWithJson.java index ac61b25cd..ae8a5bbd5 100644 --- a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryImdg.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryWithJson.java @@ -15,20 +15,20 @@ import java.util.function.BiConsumer; * Comparing actual and expected objects via AssertJ * Support converting json MvcResult to objects for comparation. */ -public class MatcherFactoryImdg { +public class MatcherFactoryWithJson { - public static Matcher usingAssertions(Class clazz, BiConsumer assertion, BiConsumer, Iterable> iterableAssertion) { + public static Matcher usingAssertionsForClass(Class clazz, BiConsumer assertion, BiConsumer, Iterable> iterableAssertion) { return new Matcher<>(clazz, assertion, iterableAssertion); } - public static Matcher usingEqualsComparator(Class clazz) { - return usingAssertions(clazz, + public static Matcher usingEqualsComparatorForClass(Class clazz) { + return usingAssertionsForClass(clazz, (a, e) -> Assertions.assertThat(a).isEqualTo(e), (a, e) -> Assertions.assertThat(a).isEqualTo(e)); } - public static Matcher usingIgnoringFieldsComparator(Class clazz, String... fieldsToIgnore) { - return usingAssertions(clazz, + public static Matcher usingIgnoringFieldsComparatorForClass(Class clazz, String... fieldsToIgnore) { + return usingAssertionsForClass(clazz, (a, e) -> Assertions.assertThat(a).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(e), (a, e) -> Assertions.assertThat(a).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(e)); } diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/TestUtils.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/TestUtils.java deleted file mode 100644 index 9c109a595..000000000 --- a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/TestUtils.java +++ /dev/null @@ -1,95 +0,0 @@ -package ru.spcex.clearing.imdg; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.consumer.MockConsumer; -import org.apache.kafka.clients.producer.RecordMetadata; -import org.apache.kafka.common.TopicPartition; -import ru.spcex.clearing.platform.messaging.domain.ActionType; -import ru.spcex.clearing.platform.messaging.domain.BaseRequest; -import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.imdg.api.Imdg; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -public class TestUtils { - private static final ObjectMapper objectMapper = new ObjectMapper(); - - public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) { - TopicPartition tp = new TopicPartition(topic, partition); - HashMap startOffsets = new HashMap<>(); - startOffsets.put(tp, 0L); - mockConsumer.updateBeginningOffsets(startOffsets); - mockConsumer.schedulePollTask(() -> { - mockConsumer.rebalance(Collections.singletonList(tp)); - mockConsumer.addRecord(new ConsumerRecord<>(topic, partition, offset, "key", jsonValue)); - }); - } - - public static String getJsonStringForNew(T accountRequest, long id) { - return getJsonBaseRequest(accountRequest, id, ActionType.NEW); - } - - public static String getJsonStringForUPDATE(T accountRequest, long id) { - return getJsonBaseRequest(accountRequest, id, ActionType.UPDATE); - } - - public static String getJsonStringForDELETE(T accountRequest, long id) { - return getJsonBaseRequest(accountRequest, id, ActionType.DELETE); - } - - private static String getJsonBaseRequest(T accountRequest, long id, ActionType actionType) { - BaseRequest baseRequest = new BaseRequest<>(); - baseRequest.setRequestPayload(accountRequest); - baseRequest.setId(id); - baseRequest.setActionType(actionType); - String jsonBaseRequest; - try { - jsonBaseRequest = objectMapper.writeValueAsString(baseRequest); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - return jsonBaseRequest; - } - - public static void clearImdg(Imdg imdg) { - Collection values = imdg.getAllValues(); - for (T val : values) { - imdg.delete(val); - } - } - - public static class FutureRecordMetadata implements Future { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return false; - } - - @Override - public RecordMetadata get() throws InterruptedException, ExecutionException { - return null; - } - - @Override - public RecordMetadata get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return null; - } - } -} From 83a513f629eb316c2025a958ac8a5758928a49cd Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 7 Apr 2023 17:59:28 +0300 Subject: [PATCH 87/90] company-service CompanyService, CompanySymbolService --- .../CompanySymbolValidationConfig.java | 106 ++++++++++++++ .../company/service/CompanyService.java | 44 +++--- .../company/service/CompanySymbolService.java | 129 ++++++++++++++++-- .../service/CompanyInfoServiceTest.java | 3 + .../company/service/CompanyServiceTest.java | 4 + .../service/CompanySymbolServiceTest.java | 42 +++++- .../platform/messaging/domain/Consts.java | 1 + 7 files changed, 299 insertions(+), 30 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java new file mode 100644 index 000000000..3277c69ef --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java @@ -0,0 +1,106 @@ +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.CompanySymbols; +import ru.clearing.platform.dictionary.*; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.company.validation.CompanySymbolNotExistRule; +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.CompanyInfoUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +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.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.CompanySymbol; +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 CompanySymbolValidationConfig { + + @Bean("companySymbolNewRequestValidator") + public Function companySymbolNewRequestValidator(Map> imdgForValidation) { + return companySymbolUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(companySymbolUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); +// addImdg.accept(IMDGDistributedNames.Map_CompanySymbols); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); + addImdg.accept(IMDGDistributedNames.Map_Company); + return new ValidatorImpl<>(context, + FieldRequiredRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + IdPresentRule.instance("companyId", + CompanySymbolUpdateRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound), +// FieldRequiredRule.instance("companySymbol", CompanySymbolUpdateRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("companySymbolValue", CompanySymbolUpdateRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("companySymbol", + CompanySymbolUpdateRequest::getCompanySymbol, + IMDGDistributedNames.Map_CompanySymbolDictionary, + CompanySymbolDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false) + // , new CompanySymbolNotExistRule() чтобы применить это правило, необходимо сделать дополнительный тип в его методе + ); + }; + } + + @Bean("companySymbolUpdateRequestValidator") + public Function companySymbolUpdateRequestValidator(Map> imdgForValidation) { + return companySymbolUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(companySymbolUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbols); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); + addImdg.accept(IMDGDistributedNames.Map_Company); + return new ValidatorImpl>(context, + IdPresentRule.instance("id", + CompanySymbolUpdateRequest::getId, + IMDGDistributedNames.Map_CompanySymbols, + CompanySymbols.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyInfoNotFound, + (CompanySymbols existSymbol) -> { + assert existSymbol.getId().equals(context.getValidatedObject().getId()); + return existSymbol.getCompanySymbol().equals(context.getValidatedObject().getCompanySymbol()) + ? null : CompanyErrors.EditCompanySymbols; + }), + + FieldRequiredRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + IdPresentRule.instance("companyId", + CompanySymbolUpdateRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound), +// FieldRequiredRule.instance("companySymbol", CompanySymbolUpdateRequest::getCompanySymbol, CompanyErrors.RequiredFieldEmpty), +// FieldRequiredRule.instance("companySymbolValue", CompanySymbolUpdateRequest::getCompanySymbolValue, CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("companySymbol", + CompanySymbolUpdateRequest::getCompanySymbol, + IMDGDistributedNames.Map_CompanySymbolDictionary, + CompanySymbolDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false) + ); + }; + } +} 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 3fc6f9a6e..cc9d7c2f3 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 @@ -22,12 +22,15 @@ 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.CompanySymbol; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; +import 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; @@ -42,10 +45,8 @@ public class CompanyService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final RequestHelper requestHelper; private final ImdgProvider imdgProvider; - private final Imdg companySymbolsMap; private final ImdgId idSequence; protected UserRoleVerification userRoleVerification; - protected IMessageResolver messageResolver; private ValidationHelper validationHelper; private Function companyNewRequestValidator; @@ -77,14 +78,15 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.imdgProvider = imdgProvider; this.requestHelper = requestHelper.setLogger(log); - this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.idSequence = imdgProvider.getImdgIdGenerator(); this.userRoleVerification = userRoleVerification; + userRoleVerification.setRoleForVerification(UserRole.Admin); this.validationHelper = validationHelper; this.companyNewRequestValidator = companyNewRequestValidator; this.companyUpdateRequestValidator = companyUpdateRequestValidator; this.companyDeleteRequestValidator = companyDeleteRequestValidator; this.companySymbolService = companySymbolService; + companySymbolService.setCompanyService(this); this.accountNotification = accountNotification; this.relationHelper = relationHelper; } @@ -213,18 +215,36 @@ public class CompanyService extends QueueConsumer implements InitializingBean { assert company.getId().equals(companySymbol.getCompanyId()); if (CompanySymbol.TRDC.equalsByKey(companySymbol.getCompanySymbol())) { company.setTradingCode(companySymbol.getCompanySymbolValue()); - } else { - company.setTradingCode(null); } if (CompanySymbol.CLRC.equalsByKey(companySymbol.getCompanySymbol())) { company.setClearingCode(companySymbol.getCompanySymbolValue()); - } else { - company.setClearingCode(null); } if (CompanySymbol.RGRC.equalsByKey(companySymbol.getCompanySymbol())) { company.setRegistrationCode(companySymbol.getCompanySymbolValue()); + } + } + + public synchronized void updateCompanyBySymbol(ImdgTransaction transaction, CompanySymbols companySymbol) throws ClearingBaseException { + if (companySymbol.getCompanyId() == null) { + throw new IllegalArgumentException("Required companySymbol.companyId"); + } + if (CompanySymbol.TRDC.equalsByKey(companySymbol.getCompanySymbol()) + || CompanySymbol.CLRC.equalsByKey(companySymbol.getCompanySymbol()) + || CompanySymbol.RGRC.equalsByKey(companySymbol.getCompanySymbol())) { + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + Company company = companyMap.getSingleObjectByID(companySymbol.getCompanyId()); + if (company == null) { + throw new ClearingBaseException(new EnumMessage(CompanyErrors.CompanyNotFound, companySymbol.getCompanyId())); + } + updateCompanyBySymbol(company, companySymbol); + company.setUpdated(Instant.now()); + companyMap.update(company); + log.debug("Company {} updated by change CompanySymbols {} ({})", + company.getId(), companySymbol.getId(), companySymbol.getCompanySymbol()); } else { - company.setRegistrationCode(null); + log.trace("No need update company {} by changed companySymbols {}", + companySymbol.getCompanyId(), companySymbol.getCompanySymbol()); } } @@ -257,14 +277,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { company.setUpdated(Instant.now()); - CompanySymbols companySymbol = companySymbolsMap.getSingleObjectByFieldValues(Map.of("companyId", company.getId())); - if (companySymbol == null) { - log.warn("CompanySymbols not found for companyId={}", company.getId()); - } else { - log.trace("Found CompanySymbols.id={} for companyId={}", companySymbol.getId(), company.getId()); - updateCompanyBySymbol(company, companySymbol); - } - String prevStatus = company.getWorkflowStatus(); company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); 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 080a82d3a..fce285051 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 @@ -7,51 +7,159 @@ 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.CompanySymbols; +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.company.CompanySymbolUpdateRequest; 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.UserRole; 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.ClearingBaseException; +import ru.spcex.platform.utils.validation.IValidator; import java.util.Objects; +import java.util.function.Function; @Service public class CompanySymbolService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); - private final Imdg companySymbolsMap; + private final ImdgProvider imdgProvider; + // private final Imdg companySymbolsMap; private final ImdgId idSequence; + protected CompanyService companyService; + + private final RequestHelper requestHelper; + protected ValidationHelper validationHelper; + protected UserRoleVerification userRoleVerification; + protected Function companySymbolNewRequestValidator; + protected Function companySymbolUpdateRequestValidator; @Autowired public CompanySymbolService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider) { + ImdgProvider imdgProvider, + RequestHelper requestHelper, + ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, + @Qualifier("companySymbolNewRequestValidator") + Function companySymbolNewRequestValidator, + @Qualifier("companySymbolUpdateRequestValidator") + Function companySymbolUpdateRequestValidator + ) { super(kafkaQueue, kafkaProducer); - this.companySymbolsMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + this.imdgProvider = imdgProvider; this.idSequence = imdgProvider.getImdgIdGenerator(); + + this.requestHelper = requestHelper.setLogger(log); + this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; + userRoleVerification.setRoleForVerification(UserRole.Admin); + this.companySymbolNewRequestValidator = companySymbolNewRequestValidator; + this.companySymbolUpdateRequestValidator = companySymbolUpdateRequestValidator; } @Override public void afterPropertiesSet() { callback(CompanySymbolUpdateRequest.class) - .setConsumer(this::companySymbolUpdate) + .setFunction(this::companySymbolNew) + .forDestination(Consts.DESTINATION_COMPANY_SYMBOL_NEW, callbacks::put); + callback(CompanySymbolUpdateRequest.class) + .setFunction(this::companySymbolUpdate) .forDestination(Consts.DESTINATION_COMPANY_SYMBOL_UPDATE, callbacks::put); init(); } - public void companySymbolUpdate(BaseRequest userRequest) { - CompanySymbolUpdateRequest req = userRequest.getRequestPayload(); - log.debug("CompanySymbolUpdateRequest received"); - CompanySymbols companySymbols = companySymbolsMap.getSingleObjectByID(req.getId()); -// companySymbols.setCompanySymbol(req.getCompanySymbol()); по ТЗ не должен менятся при обновлении + public void setCompanyService(CompanyService companyService) { + this.companyService = companyService; + } + + + public RequestInfoUpdate companySymbolNew(BaseRequest symbolRequest) { + CompanySymbolUpdateRequest req = symbolRequest.getRequestPayload(); + log.debug("CompanySymbolNewRequest received, id={}", symbolRequest.getId()); + { // validate + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(symbolRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(symbolRequest, companySymbolNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + + + CompanySymbols companySymbols = new CompanySymbols(); + companySymbols.setId(idSequence.nextId()); + companySymbols.setCompanyId(req.getCompanyId()); + companySymbols.setCompanySymbol(req.getCompanySymbol()); companySymbols.setCompanySymbolValue(req.getCompanySymbolValue()); - companySymbolsMap.update(companySymbols); + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Imdg companySymbolsMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbolsMap.update(companySymbols); + try { + companyService.updateCompanyBySymbol(transaction, companySymbols); + } catch (ClearingBaseException e) { + return requestHelper.makeErrorResponse(symbolRequest, e.getEnumMsg()); + } + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + log.debug("successfully processed, id {}", companySymbols.getId()); + return null; + } + + public RequestInfoUpdate companySymbolUpdate(BaseRequest symbolRequest) { + CompanySymbolUpdateRequest req = symbolRequest.getRequestPayload(); + log.debug("CompanySymbolUpdateRequest received, id={}", symbolRequest.getId()); + + { // validate + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(symbolRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(symbolRequest, companySymbolUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + CompanySymbols companySymbols; + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Imdg companySymbolsMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbols = companySymbolsMap.getSingleObjectByID(req.getId()); +// companySymbols.setCompanySymbol(req.getCompanySymbol()); по ТЗ не должен менятся при обновлении + companySymbols.setCompanySymbolValue(req.getCompanySymbolValue()); + companySymbolsMap.update(companySymbols); + try { + companyService.updateCompanyBySymbol(transaction, companySymbols); + } catch (ClearingBaseException e) { + return requestHelper.makeErrorResponse(symbolRequest, e.getEnumMsg()); + } + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + + log.debug("successfully processed, id {}", companySymbols.getId()); + return null; } @@ -64,6 +172,7 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB newSymbol.setCompanySymbolValue(companySymbolValue); log.debug("Created new companySymbols.id={} for company {}", newSymbol.getId(), companyId); if (transaction == null) { + Imdg companySymbolsMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); companySymbolsMap.insert(newSymbol); } else { Imdg tMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); 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 8ab19f2f4..d3b9d46c1 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.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; @@ -40,6 +41,8 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanyInfoService.class, + CompanyValidationConfig.class, + CompanySymbolValidationConfig.class, CompanyService.class, CompanyValidationConfig.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 9e6f01dae..4dff5bd7e 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.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.error.CompanyErrors; @@ -54,6 +55,9 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; AccountNotificationHelper.class, RelationHelper.class, + CompanySymbolService.class, + CompanySymbolValidationConfig.class, + KafkaConfigTest.class, HazelcastServiceTestConfiguration.class, BeanConfiguration.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 7ddfaaaee..8b8d37341 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 @@ -13,14 +13,21 @@ 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.CompanySymbols; +import ru.clearing.platform.dictionary.CompanySymbolDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.company.config.KafkaConfigTest; +import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; +import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.utils.MatcherFactory; import ru.spcex.clearing.company.utils.TestUtils; 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.company.CompanySymbolUpdateRequest; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.CompanySymbol; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @@ -34,6 +41,16 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanySymbolService.class, + + CompanySymbolValidationConfig.class, + ValidationConfig.class, + BeanConfiguration.class, + + CompanyService.class, + CompanyValidationConfig.class, + AccountNotificationHelper.class, + RelationHelper.class, + KafkaConfigTest.class, HazelcastServiceTestConfiguration.class}) class CompanySymbolServiceTest { @@ -60,6 +77,23 @@ class CompanySymbolServiceTest { hazelcastServiceTest.waitAvailable(); companySymbolsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + + 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(12L); + cioSymbol.setCode(CompanySymbol.CIO.getKey()); + cioSymbol.setName(CompanySymbol.CIO.getKey()); + companySymbolDictionaryImdg.insert(cioSymbol); + } + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); doReturn(future).when(mockProducer).send(producerRecord.capture()); } @@ -80,20 +114,20 @@ class CompanySymbolServiceTest { CompanySymbols existsCompanySymbols = new CompanySymbols(); existsCompanySymbols.setId(ID); existsCompanySymbols.setCompanyId(ID); - existsCompanySymbols.setCompanySymbol("0000"); - existsCompanySymbols.setCompanySymbolValue("exists companySymbolValue"); + existsCompanySymbols.setCompanySymbol("CIO"); + existsCompanySymbols.setCompanySymbolValue("CIO exists companySymbolValue"); companySymbolsImdg.insert(existsCompanySymbols); CompanySymbolUpdateRequest companySymbolUpdateRequest = new CompanySymbolUpdateRequest(); companySymbolUpdateRequest.setId(ID); companySymbolUpdateRequest.setCompanyId(ID); - companySymbolUpdateRequest.setCompanySymbol("1234"); + companySymbolUpdateRequest.setCompanySymbol("CIO"); companySymbolUpdateRequest.setCompanySymbolValue(companySymbolValue); CompanySymbols predictableCompanySymbols = new CompanySymbols(); predictableCompanySymbols.setId(ID); predictableCompanySymbols.setCompanyId(ID); - predictableCompanySymbols.setCompanySymbol("0000"); + predictableCompanySymbols.setCompanySymbol("CIO"); predictableCompanySymbols.setCompanySymbolValue(companySymbolValue); //ACT 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 2a235f2d0..1d3809845 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 @@ -43,6 +43,7 @@ public interface Consts { String DESTINATION_COMPANY_BLOCK = "company-block"; String DESTINATION_COMPANY_INFO_NEW = "company-info-new"; String DESTINATION_COMPANY_INFO_UPDATE = "company-info-update"; + String DESTINATION_COMPANY_SYMBOL_NEW = "company-symbol-new"; String DESTINATION_COMPANY_SYMBOL_UPDATE = "company-symbol-update"; String DESTINATION_COMPANY_ROLE_SET_NEW = "companyroleset-new"; String DESTINATION_COMPANY_ROLE_SET_DELETE = "companyroleset-delete"; From e821423e68043ed0c9ac0547a50bb8f2a8d68ff1 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 7 Apr 2023 18:09:08 +0300 Subject: [PATCH 88/90] =?UTF-8?q?company-service=20CompanySymbolValidation?= =?UTF-8?q?Config=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=BE=20=D0=B2=D0=B0?= =?UTF-8?q?=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 --- .../CompanySymbolValidationConfig.java | 5 ++- .../company/service/CompanySymbolService.java | 15 ++++---- ...ySymbolOfSymbolNewRequestNotExistRule.java | 38 +++++++++++++++++++ 3 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java index 3277c69ef..8c747cfef 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java @@ -7,6 +7,7 @@ import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.company.validation.CompanySymbolNotExistRule; +import ru.spcex.clearing.company.validation.CompanySymbolOfSymbolNewRequestNotExistRule; 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.CompanyInfoUpdateRequest; @@ -56,8 +57,8 @@ public class CompanySymbolValidationConfig { CompanySymbolDictionary.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.WrongFieldValue, - false) - // , new CompanySymbolNotExistRule() чтобы применить это правило, необходимо сделать дополнительный тип в его методе + false), + new CompanySymbolOfSymbolNewRequestNotExistRule() ); }; } 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 fce285051..85c0469f8 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 @@ -34,7 +34,6 @@ import java.util.function.Function; public class CompanySymbolService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final ImdgProvider imdgProvider; - // private final Imdg companySymbolsMap; private final ImdgId idSequence; protected CompanyService companyService; @@ -105,8 +104,8 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB transaction.beginTransaction(); boolean txOk = false; try { - Imdg companySymbolsMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); - companySymbolsMap.update(companySymbols); + Imdg companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbolsTMap.update(companySymbols); try { companyService.updateCompanyBySymbol(transaction, companySymbols); } catch (ClearingBaseException e) { @@ -140,11 +139,11 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB transaction.beginTransaction(); boolean txOk = false; try { - Imdg companySymbolsMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); - companySymbols = companySymbolsMap.getSingleObjectByID(req.getId()); + Imdg companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbols = companySymbolsTMap.getSingleObjectByID(req.getId()); // companySymbols.setCompanySymbol(req.getCompanySymbol()); по ТЗ не должен менятся при обновлении companySymbols.setCompanySymbolValue(req.getCompanySymbolValue()); - companySymbolsMap.update(companySymbols); + companySymbolsTMap.update(companySymbols); try { companyService.updateCompanyBySymbol(transaction, companySymbols); } catch (ClearingBaseException e) { @@ -172,8 +171,8 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB newSymbol.setCompanySymbolValue(companySymbolValue); log.debug("Created new companySymbols.id={} for company {}", newSymbol.getId(), companyId); if (transaction == null) { - Imdg companySymbolsMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); - companySymbolsMap.insert(newSymbol); + Imdg companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbolsTMap.insert(newSymbol); } else { Imdg tMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); tMap.insert(newSymbol); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java new file mode 100644 index 000000000..1e15c4986 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolOfSymbolNewRequestNotExistRule.java @@ -0,0 +1,38 @@ +package ru.spcex.clearing.company.validation; + +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; +import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; + +/** + * Проверка наличия CompanySymbols с переданными в запросе companySymbol и companyId + */ +public class CompanySymbolOfSymbolNewRequestNotExistRule implements IValidationRule> { + @Override + public Optional validate(ImdgValidationContext context) { + CompanySymbolUpdateRequest request = context.getValidatedObject(); + + Imdg companySymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + + Collection companySymbols = companySymbolsImdg.getCollectionObjectsByFieldValues(Map.of( + "companyId", request.getCompanyId(), + "companySymbol", request.getCompanySymbol() + )); + if (companySymbols.isEmpty()) return Optional.empty(); + return of(CompanyErrors.RecordAlreadyExist, request.getCompanyId(), request.getCompanySymbol()); + } +} From 42943216136d81e24ee2827c1f7481aedd87b199 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Fri, 7 Apr 2023 18:25:11 +0300 Subject: [PATCH 89/90] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-258?= =?UTF-8?q?=20=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=89=D0=B8=D0=B5=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D1=8B=20?= =?UTF-8?q?=D0=B8=20=D0=BA=D0=BE=D0=BD=D1=84=D0=B8=D0=B3=D0=B8=20=D0=B2=20?= =?UTF-8?q?test-clearing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Jackson2HttpConverterTestConfig.java | 2 +- .../queue/AbstractControllerTest.java | 10 +- .../account/BankAccountControllerTest.java | 2 +- ...tClearingMemberCategoryControllerTest.java | 2 +- .../EditCompanyInfoControllerTest.java | 2 +- .../EditCompanySymbolControllerTest.java | 2 +- .../company/EditContactControllerTest.java | 2 +- .../queue/company/RelationControllerTest.java | 2 +- .../misc/NotificationControllerTest.java | 2 +- .../queue/misc/SessionControllerTest.java | 2 +- .../PaymentInstructionControllerTest.java | 2 +- .../scheduler/LauncherControllerTest.java | 4 +- .../PlannerAllTodayControllerTest.java | 2 +- .../scheduler/PlannerControllerTest.java | 2 +- .../queue/user/UserControllerTest.java | 2 +- .../utilities/StatementControllerTest.java | 2 +- clearing-parent/company-service/pom.xml | 5 + .../HazelcastServiceTestConfiguration.java | 71 --------- .../company/config/KafkaConfigTest.java | 44 ------ .../ClearingMemberCategoryServiceTest.java | 24 +-- .../service/CompanyInfoServiceTest.java | 20 +-- .../company/service/CompanyServiceTest.java | 20 +-- .../service/CompanySymbolServiceTest.java | 20 +-- .../company/service/ContactServiceTest.java | 21 ++- .../service/ProfileDocumentServiceTest.java | 24 +-- .../company/utils/MatcherFactory.java | 38 ----- .../clearing/company/utils/TestUtils.java | 149 ------------------ .../service/AbstractServiceTest.java | 10 +- .../service/CouponPeriodServiceTest.java | 6 +- .../service/CurrencyServiceTest.java | 6 +- .../service/EquitySecurityServiceTest.java | 6 +- .../FixedIncomeCashFlowServiceTest.java | 12 +- .../FixedIncomeSecurityServiceTest.java | 6 +- .../MoneyMarketSecurityServiceTest.java | 6 +- clearing-parent/test-clearing/pom.xml | 9 ++ .../ru/spcex/clearing/test}/ImapEvent.java | 2 +- .../clearing/{ => test}/MatcherFactory.java | 2 +- .../spcex/clearing/{ => test}/TestUtils.java | 5 +- .../clearing/test}/config/ImdgTestConfig.java | 2 +- .../test}/config/KafkaTestConfig.java | 2 +- .../{imdg => test/json}/JsonUtil.java | 2 +- .../json}/MatcherFactoryWithJson.java | 2 +- 42 files changed, 134 insertions(+), 422 deletions(-) delete mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java delete mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/KafkaConfigTest.java delete mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/MatcherFactory.java delete mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java rename clearing-parent/{company-service/src/test/java/ru/spcex/clearing/company/utils => test-clearing/src/main/java/ru/spcex/clearing/test}/ImapEvent.java (98%) rename clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/{ => test}/MatcherFactory.java (97%) rename clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/{ => test}/TestUtils.java (98%) rename clearing-parent/{securities-service/src/test/java/ru/spcex/clearing/securities => test-clearing/src/main/java/ru/spcex/clearing/test}/config/ImdgTestConfig.java (98%) rename clearing-parent/{securities-service/src/test/java/ru/spcex/clearing/securities => test-clearing/src/main/java/ru/spcex/clearing/test}/config/KafkaTestConfig.java (97%) rename clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/{imdg => test/json}/JsonUtil.java (98%) rename clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/{imdg => test/json}/MatcherFactoryWithJson.java (98%) diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java index 7cabe0661..8fcdb0590 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/config/Jackson2HttpConverterTestConfig.java @@ -4,7 +4,7 @@ package ru.spcex.clearing.backendapi.controller.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import ru.spcex.clearing.imdg.JsonUtil; +import ru.spcex.clearing.test.json.JsonUtil; @Configuration public class Jackson2HttpConverterTestConfig { diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java index 6e0cf32b8..68be40768 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/AbstractControllerTest.java @@ -27,7 +27,6 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import ru.clearing.classes.statics.data.user.User; -import ru.spcex.clearing.TestUtils; import ru.spcex.clearing.backendapi.controller.config.*; import ru.spcex.clearing.backendapi.controller.queue.account.AccountBalanceController; import ru.spcex.clearing.backendapi.controller.queue.account.AccountController; @@ -59,9 +58,10 @@ import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllRespo import ru.spcex.clearing.backendapi.domain.actions.IAction; import ru.spcex.clearing.backendapi.meta.GetResponseFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.imdg.MatcherFactoryWithJson; import ru.spcex.clearing.platform.messaging.domain.ActionType; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.test.TestUtils; +import ru.spcex.clearing.test.json.MatcherFactoryWithJson; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @@ -80,9 +80,9 @@ import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.readValue; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; -import static ru.spcex.clearing.imdg.MatcherFactoryWithJson.usingIgnoringFieldsComparatorForClass; +import static ru.spcex.clearing.test.json.JsonUtil.readValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.MatcherFactoryWithJson.usingIgnoringFieldsComparatorForClass; @ContextConfiguration(classes = { diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java index 9d92d02c0..ae92ef4eb 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/account/BankAccountControllerTest.java @@ -22,7 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class BankAccountControllerTest extends AbstractControllerTest { private static final String REST_URL = "/securities/bank-accounts/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java index 513fd21b0..1126570ca 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditClearingMemberCategoryControllerTest.java @@ -15,7 +15,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class EditClearingMemberCategoryControllerTest extends AbstractControllerTest { private static final String REST_URL = "/clearing-member-categories/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java index 305ea3263..6e97f2d8e 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanyInfoControllerTest.java @@ -24,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class EditCompanyInfoControllerTest extends AbstractControllerTest { private static final String REST_URL = "/company-infos/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java index a84ecfed5..8aed79ead 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditCompanySymbolControllerTest.java @@ -14,7 +14,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class EditCompanySymbolControllerTest extends AbstractControllerTest { private static final String REST_URL = "/company-symbols/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java index 6d0fa2f85..b445858aa 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/EditContactControllerTest.java @@ -15,7 +15,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class EditContactControllerTest extends AbstractControllerTest { private static final String REST_URL = "/contacts/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java index 6a99f321c..e2f06a22c 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/company/RelationControllerTest.java @@ -14,7 +14,7 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import static org.junit.jupiter.api.Assertions.assertThrows; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class RelationControllerTest extends AbstractControllerTest { private static final String REST_URL = "/relations/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java index 6fd8344ed..e0cb15aad 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/NotificationControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class NotificationControllerTest extends AbstractControllerTest { private static final String REST_URL = "/notifications/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java index 925b3d210..578af6a9e 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/misc/SessionControllerTest.java @@ -16,7 +16,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class SessionControllerTest extends AbstractControllerTest { private static final String REST_URL = "/sessions/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java index ef55f77f3..e1de08c64 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/payment/PaymentInstructionControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class PaymentInstructionControllerTest extends AbstractControllerTest { private static final String REST_URL = "/payment-instructions/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java index dde70e1e8..dad895ccd 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/LauncherControllerTest.java @@ -29,8 +29,8 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.readValue; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.readValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class LauncherControllerTest extends AbstractControllerTest { private static final String REST_URL = "/launchers/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java index cdbac036e..78553ec70 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerAllTodayControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class PlannerAllTodayControllerTest extends AbstractControllerTest { private static final String REST_URL = "/schedule/planners-all-today/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java index e107dab46..019d5038d 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/scheduler/PlannerControllerTest.java @@ -17,7 +17,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class PlannerControllerTest extends AbstractControllerTest { private static final String REST_URL = "/schedule/planners/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java index 90f222444..015b40266 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/user/UserControllerTest.java @@ -18,7 +18,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.readValue; +import static ru.spcex.clearing.test.json.JsonUtil.readValue; class UserControllerTest extends AbstractControllerTest { public static final String REST_URL = "/users/"; diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java index 0a418d31c..added83eb 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/utilities/StatementControllerTest.java @@ -16,7 +16,7 @@ import java.util.Map; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static ru.spcex.clearing.imdg.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class StatementControllerTest extends AbstractControllerTest { public static final String REST_URL = "/statements/"; diff --git a/clearing-parent/company-service/pom.xml b/clearing-parent/company-service/pom.xml index ee17025df..3143aecaa 100644 --- a/clearing-parent/company-service/pom.xml +++ b/clearing-parent/company-service/pom.xml @@ -53,6 +53,11 @@ spring-boot-starter-test test + + ru.spcex.clearing + test-clearing + test + diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java deleted file mode 100644 index 5605eaff9..000000000 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java +++ /dev/null @@ -1,71 +0,0 @@ -package ru.spcex.clearing.company.config; - -import com.hazelcast.config.*; -import com.hazelcast.core.Hazelcast; -import com.hazelcast.core.HazelcastInstance; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams; -import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; -import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper; - -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; - -@Configuration -public class HazelcastServiceTestConfiguration { - - public static final AtomicLong currentID = new AtomicLong(0L); - private HazelcastInstance hazelcastInstance; - - private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) { - ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor(); - if (maxPoolSz > 2) { - pool.setKeepAliveSeconds(60); - pool.setAllowCoreThreadTimeOut(true); - } - pool.setCorePoolSize(maxPoolSz); - pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion); - return pool; - } - - @Bean(name = "hazelcastServiceTest") - public HazelcastService hazelcastService(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, HazelcastClientParams params) { - Config cfg = new Config(); - cfg.setInstanceName("localhost"); - - NetworkConfig networkConfig = new NetworkConfig(); - JoinConfig joinConfig = new JoinConfig(); - joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false)); - joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1"))); - networkConfig.setJoin(joinConfig); - cfg.setNetworkConfig(networkConfig); - hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg); - HazelcastHelper.imdgSystem_setStorageState(true, hazelcastInstance); - return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params); - } - - @Bean(name = "taskExecutorHazelcastClientInitializer") - public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() { - return createThreadPoolTaskExecutor(1, true); - } - - @Bean(name = "taskExecutorIdGeneratorAwaiter") - public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() { - return createThreadPoolTaskExecutor(1, false); - } - - @Bean(name = "hazelcastClientParams") - public HazelcastClientParams getHazelcastClientParams() { - HazelcastClientParams params = new HazelcastClientParams(); - params.setLogin("dev"); - params.setPassword("dev-pass"); - params.setClusterMembers("127.0.0.1"); - params.setInstanceName("hzTestClient" + new Random().nextInt()); - params.setNearCacheConfig(new NearCacheConfig()); - return params; - } -} diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/KafkaConfigTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/KafkaConfigTest.java deleted file mode 100644 index ce31fb986..000000000 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/KafkaConfigTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.spcex.clearing.company.config; - - -import org.apache.kafka.clients.consumer.MockConsumer; -import org.apache.kafka.clients.consumer.OffsetResetStrategy; -import org.apache.kafka.clients.producer.Producer; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; -import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.platform.messaging.service.RequestInfo; -import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; -import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.api.ImdgId; -import ru.spcex.platform.imdg.api.ImdgProvider; - -@Configuration -public class KafkaConfigTest { - - @Autowired - @Bean(name = "kafkaSenderTest") - public KafkaSender kafkaSender(Producer kafkaProducer, @Qualifier("hazelcastServiceTest") ImdgProvider imdgProvider) { - ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator(); - return KafkaSender - .setup() - .producer(kafkaProducer) - .idGenerator(imdgIdGenerator::nextId) - .imdgProvider(s -> { - Imdg imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class); - return imdg::insert; - }) - .build(); - } - - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - @Bean(name = "mockConsumerTest") - public MockConsumer createConsumer() { - return new MockConsumer<>(OffsetResetStrategy.EARLIEST); - } - -} diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java index df802532f..25a487333 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClearingMemberCategoryServiceTest.java @@ -17,30 +17,30 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.generated.ClearingMemberCategory; import ru.clearing.platform.dictionary.ClearingCategoryDictionary; import ru.spcex.clearing.company.config.BeanConfiguration; -import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.ClearingMemberCategoryValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; -import ru.spcex.clearing.company.utils.MatcherFactory.Matcher; -import ru.spcex.clearing.company.utils.TestUtils; 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.ClearingMemberCategoryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; +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.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.imdg.api.ImdgProvider; import javax.annotation.PostConstruct; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration.currentID; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { @@ -48,11 +48,11 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; ValidationConfig.class, ClearingMemberCategoryService.class, ClearingMemberCategoryValidationConfig.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + KafkaTestConfig.class, + ImdgTestConfig.class}) class ClearingMemberCategoryServiceTest { - public static final Matcher MEMBER_CATEGORY_MATCHER = usingIgnoringFieldsComparator(); + public static final MatcherFactory.Matcher MEMBER_CATEGORY_MATCHER = usingIgnoringFieldsComparator(); private static final int PARTITION = 0; private static final String TOPIC_MEMBER_CATEGORY_NEW = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_NEW; private static final String TOPIC_MEMBER_CATEGORY_UPDATE = Consts.DESTINATION_CLEARING_MEMBER_CATEGORY_UPDATE; @@ -62,7 +62,7 @@ class ClearingMemberCategoryServiceTest { ClearingMemberCategoryService clearingMemberCategoryService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg memberCategoryImdg; @Captor 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 8ab19f2f4..65269737b 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 @@ -16,26 +16,26 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.profile.CompanyInfo; import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.company.config.BeanConfiguration; -import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; -import ru.spcex.clearing.company.utils.MatcherFactory; -import ru.spcex.clearing.company.utils.TestUtils; 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.company.CompanyInfoUpdateRequest; +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.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.imdg.api.ImdgProvider; import javax.annotation.PostConstruct; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { @@ -49,8 +49,8 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; RelationHelper.class, BeanConfiguration.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + KafkaTestConfig.class, + ImdgTestConfig.class}) class CompanyInfoServiceTest { public static final MatcherFactory.Matcher COMPANY_INFO_MATCHER = usingIgnoringFieldsComparator(); @@ -61,7 +61,7 @@ class CompanyInfoServiceTest { CompanyInfoService companyInfoService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg companyImdg; @Captor 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 9e6f01dae..ebc454f79 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 @@ -19,22 +19,22 @@ import ru.clearing.classes.statics.data.generated.ClearingMemberCategory; 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.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.utils.MatcherFactory; -import ru.spcex.clearing.company.utils.TestUtils; 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.TestUtils; +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.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.imdg.api.ImdgProvider; import javax.annotation.PostConstruct; import java.util.Arrays; @@ -42,8 +42,8 @@ import java.util.Map; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { @@ -54,8 +54,8 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; AccountNotificationHelper.class, RelationHelper.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class, + KafkaTestConfig.class, + ImdgTestConfig.class, BeanConfiguration.class}) class CompanyServiceTest { @@ -67,7 +67,7 @@ class CompanyServiceTest { CompanyService companyService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg companyImdg; private Imdg companySymbolsImdg; private Imdg workflowStatusDictionaryImdg; 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 7ddfaaaee..707a35707 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 @@ -13,29 +13,29 @@ 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.CompanySymbols; -import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; -import ru.spcex.clearing.company.utils.MatcherFactory; -import ru.spcex.clearing.company.utils.TestUtils; 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.company.CompanySymbolUpdateRequest; +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.imdg.api.Imdg; -import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.imdg.api.ImdgProvider; import javax.annotation.PostConstruct; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanySymbolService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + KafkaTestConfig.class, + ImdgTestConfig.class}) class CompanySymbolServiceTest { public static final MatcherFactory.Matcher COMPANY_SYMBOL_MATCHER = usingIgnoringFieldsComparator(); @@ -47,7 +47,7 @@ class CompanySymbolServiceTest { CompanySymbolService companySymbolService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg companySymbolsImdg; @Captor diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java index 5864d1538..dd1c9cc59 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ContactServiceTest.java @@ -16,28 +16,28 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.platform.dictionary.ContactTypeDictionary; import ru.spcex.clearing.company.config.BeanConfiguration; -import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.ContactValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; -import ru.spcex.clearing.company.utils.MatcherFactory; -import ru.spcex.clearing.company.utils.TestUtils; 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.company.ContactNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactUpdateRequest; +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.ContactTypes; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.imdg.api.ImdgProvider; import javax.annotation.PostConstruct; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { @@ -45,8 +45,8 @@ import static ru.spcex.clearing.company.utils.TestUtils.*; ValidationConfig.class, ContactValidationConfig.class, ContactService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + KafkaTestConfig.class, + ImdgTestConfig.class}) class ContactServiceTest { public static final MatcherFactory.Matcher CONTACT_MATCHER = usingIgnoringFieldsComparator(); @@ -60,7 +60,7 @@ class ContactServiceTest { @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg contactImdg; @Captor @@ -122,7 +122,6 @@ class ContactServiceTest { * Тест проверяет обновление сущности {@link Contact} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@link ContactUpdateRequest}:
* {@link ContactUpdateRequest#id} - Идентификатор записи
- * {@link ContactUpdateRequest#companyId} - Идентификатор записи
* {@link ContactUpdateRequest#contactType} - ADDR
* {@link ContactUpdateRequest#contactValue} - new ContactValue
*/ diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java index 3042b85f5..ce47319fa 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java @@ -16,21 +16,21 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.platform.dictionary.DocumentTypeDictionary; import ru.spcex.clearing.company.config.BeanConfiguration; -import ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; import ru.spcex.clearing.company.config.validation.ProfileDocumentValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; -import ru.spcex.clearing.company.utils.MatcherFactory; -import ru.spcex.clearing.company.utils.TestUtils; 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.company.ProfileDocumentNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; +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.DocumentTypes; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.imdg.api.ImdgProvider; import javax.annotation.PostConstruct; import java.time.LocalDate; @@ -38,18 +38,18 @@ import java.time.temporal.ChronoUnit; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.company.config.HazelcastServiceTestConfiguration.currentID; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { BeanConfiguration.class, ValidationConfig.class, ProfileDocumentService.class, - KafkaConfigTest.class, ProfileDocumentValidationConfig.class, - HazelcastServiceTestConfiguration.class}) + KafkaTestConfig.class, + ImdgTestConfig.class}) class ProfileDocumentServiceTest { public static final MatcherFactory.Matcher PROFILE_DOCUMENT_MATCHER = usingIgnoringFieldsComparator(); @@ -62,7 +62,7 @@ class ProfileDocumentServiceTest { ProfileDocumentService profileDocumentService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg profileDocumentMap; private Imdg companyMap; @@ -112,7 +112,7 @@ class ProfileDocumentServiceTest { } /** - * {@link ProfileDocumentService#newProfileDocument(BaseRequest)}
+ * {@link ProfileDocumentService#profileDocumentNew(BaseRequest)}
* Тест проверяет обновление сущности {@link ProfileDocument} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@link ProfileDocumentNewRequest}:
*/ diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/MatcherFactory.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/MatcherFactory.java deleted file mode 100644 index e850b89ef..000000000 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/MatcherFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.spcex.clearing.company.utils; - -import java.util.Arrays; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Factory for creating test matchers. - *

- * Comparing actual and expected objects via AssertJ - */ -public class MatcherFactory { - - public static Matcher usingIgnoringFieldsComparator(String... fieldsToIgnore) { - return new Matcher<>(fieldsToIgnore); - } - - public static class Matcher { - private final String[] fieldsToIgnore; - - private Matcher(String... fieldsToIgnore) { - this.fieldsToIgnore = fieldsToIgnore; - } - - public void assertMatch(T actual, T expected) { - assertThat(actual).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(expected); - } - - @SafeVarargs - public final void assertMatch(Iterable actual, T... expected) { - assertMatch(actual, Arrays.asList(expected)); - } - - public void assertMatch(Iterable actual, Iterable expected) { - assertThat(actual).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(expected); - } - } -} diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java deleted file mode 100644 index 1e6270839..000000000 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java +++ /dev/null @@ -1,149 +0,0 @@ -package ru.spcex.clearing.company.utils; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.consumer.MockConsumer; -import org.apache.kafka.clients.producer.MockProducer; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.apache.kafka.clients.producer.RecordMetadata; -import org.apache.kafka.common.TopicPartition; -import org.mockito.ArgumentCaptor; -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.service.RequestInfoUpdate; -import ru.spcex.clearing.platform.messaging.service.Status; -import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.imdg.api.Imdg; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.platform.messaging.service.Status.Success; - -public class TestUtils { - public static final MatcherFactory.Matcher> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(); - private static final ObjectMapper objectMapper = new ObjectMapper(); - - public static void waitingWhenAddedRecordAndCheckIt(Long id, MockProducer mockProducer, ArgumentCaptor producerRecord) { - BaseRequest predictableBaseRequest = new BaseRequest<>(); - predictableBaseRequest.setId(id); - predictableBaseRequest.setActionType(ActionType.SYSTEM); - RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate(); - requestInfoUpdate.setId(id); - requestInfoUpdate.setStatus(Success); - predictableBaseRequest.setRequestPayload(requestInfoUpdate); - - //waiting for kafka producer send message (finale event) - verify(mockProducer, timeout(30_000L).times(1)) - .send(producerRecord.capture()); - - BaseRequest baseRequestResult = (BaseRequest) producerRecord.getValue().value(); - assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic()); - BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); - } - - public static void waitingWhenTryAddRecordAndCheckError(Long id, - MockProducer mockProducer, - ArgumentCaptor producerRecord, - String errorCode, - List errorMessageArgs) { - BaseRequest predictableBaseRequest = new BaseRequest<>(); - predictableBaseRequest.setId(id); - predictableBaseRequest.setActionType(ActionType.SYSTEM); - RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate(); - requestInfoUpdate.setId(id); - requestInfoUpdate.setStatus(Status.Error); - String errorsMessage = "(%s) args [%s]".formatted(errorCode, String.join(", ", errorMessageArgs)); - requestInfoUpdate.setMessage(errorsMessage); - predictableBaseRequest.setRequestPayload(requestInfoUpdate); - - //waiting for kafka producer send message (finale event) - verify(mockProducer, timeout(30_000L).times(1)) - .send(producerRecord.capture()); - - BaseRequest baseRequestResult = (BaseRequest) producerRecord.getValue().value(); - assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic()); - BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); - } - - public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) { - TopicPartition tp = new TopicPartition(topic, partition); - HashMap startOffsets = new HashMap<>(); - startOffsets.put(tp, 0L); - mockConsumer.updateBeginningOffsets(startOffsets); - mockConsumer.schedulePollTask(() -> { - mockConsumer.rebalance(Collections.singletonList(tp)); - mockConsumer.addRecord(new ConsumerRecord<>(topic, partition, offset, "key", jsonValue)); - }); - } - - public static String getJsonStringForNew(T accountRequest, long id) { - return getJsonBaseRequest(accountRequest, id, ActionType.NEW); - } - - public static String getJsonStringForUPDATE(T accountRequest, long id) { - return getJsonBaseRequest(accountRequest, id, ActionType.UPDATE); - } - - public static String getJsonStringForDELETE(T accountRequest, long id) { - return getJsonBaseRequest(accountRequest, id, ActionType.DELETE); - } - - private static String getJsonBaseRequest(T accountRequest, long id, ActionType actionType) { - BaseRequest baseRequest = new BaseRequest<>(); - baseRequest.setRequestPayload(accountRequest); - baseRequest.setId(id); - baseRequest.setActionType(actionType); - String jsonBaseRequest; - try { - jsonBaseRequest = objectMapper.writeValueAsString(baseRequest); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - return jsonBaseRequest; - } - - public static void clearAllInImdg(Imdg imdg) { - Collection values = imdg.getAllValues(); - values.forEach(imdg::delete); - } - - public static class FutureRecordMetadata implements Future { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return false; - } - - @Override - public RecordMetadata get() throws InterruptedException, ExecutionException { - return null; - } - - @Override - public RecordMetadata get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return null; - } - } -} diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java index 98547e2bb..a7231f52d 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -18,16 +18,16 @@ import ru.clearing.classes.statics.data.misc.Currency; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; import ru.clearing.platform.dictionary.*; -import ru.spcex.clearing.MatcherFactory; -import ru.spcex.clearing.TestUtils; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.securities.component.ListingBuilder; import ru.spcex.clearing.securities.config.ErrorResolverConfig; -import ru.spcex.clearing.securities.config.ImdgTestConfig; -import ru.spcex.clearing.securities.config.KafkaTestConfig; import ru.spcex.clearing.securities.config.ValidationConfig; import ru.spcex.clearing.securities.service.cud.*; import ru.spcex.clearing.securities.validation.ValidationProvider; +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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -35,7 +35,7 @@ import java.util.concurrent.atomic.AtomicLong; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java index b1d750ea4..eada23296 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java @@ -4,19 +4,19 @@ import org.apache.kafka.clients.consumer.MockConsumer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.CouponPeriod; -import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CouponPeriodUpdateRequest; import ru.spcex.clearing.securities.service.cud.CouponPeriodService; +import ru.spcex.clearing.test.MatcherFactory; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.time.LocalDate; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; public class CouponPeriodServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher COUPON_PERIOD_MATCHER = usingIgnoringFieldsComparator(); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java index ec5ff1721..03a0cf469 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java @@ -4,17 +4,17 @@ import org.apache.kafka.clients.consumer.MockConsumer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.misc.Currency; -import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.CurrencyUpdateRequest; import ru.spcex.clearing.securities.service.cud.CurrencyService; +import ru.spcex.clearing.test.MatcherFactory; import javax.annotation.PostConstruct; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; public class CurrencyServiceTest extends AbstractServiceTest { diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java index 05d03bd67..cb3a86448 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java @@ -5,20 +5,20 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.misc.Listing; -import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.EquitySecurityUpdateRequest; import ru.spcex.clearing.securities.service.cud.EquitySecurityService; +import ru.spcex.clearing.test.MatcherFactory; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.util.Map; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; public class EquitySecurityServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher EQUITY_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java index 7f7ee673d..dad537eb0 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java @@ -13,17 +13,17 @@ 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.instrument.issue.FixedIncomeCashFlow; -import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowUpdateRequest; import ru.spcex.clearing.securities.config.ErrorResolverConfig; -import ru.spcex.clearing.securities.config.ImdgTestConfig; -import ru.spcex.clearing.securities.config.KafkaTestConfig; import ru.spcex.clearing.securities.config.ValidationConfig; import ru.spcex.clearing.securities.config.validation.FixedIncomeCashFlowValidationConfig; import ru.spcex.clearing.securities.service.cud.FixedIncomeCashFlowService; +import ru.spcex.clearing.test.MatcherFactory; +import ru.spcex.clearing.test.config.ImdgTestConfig; +import ru.spcex.clearing.test.config.KafkaTestConfig; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -31,9 +31,9 @@ import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.time.LocalDate; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.TestUtils.*; -import static ru.spcex.clearing.securities.config.ImdgTestConfig.currentID; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java index 8470d6a23..aff540631 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java @@ -5,21 +5,21 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.misc.Listing; -import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.FixedIncomeSecurityUpdateRequest; import ru.spcex.clearing.securities.service.cud.FixedIncomeSecurityService; +import ru.spcex.clearing.test.MatcherFactory; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.time.LocalDate; import java.util.Map; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; public class FixedIncomeSecurityServiceTest extends AbstractServiceTest { private static final MatcherFactory.Matcher FIXED_INCOME_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java index e65e48a91..61d5854be 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import ru.clearing.classes.statics.data.misc.Listing; import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity; -import ru.spcex.clearing.MatcherFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -15,14 +14,15 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSe import ru.spcex.clearing.platform.messaging.service.RequestInfo; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService; +import ru.spcex.clearing.test.MatcherFactory; import ru.spcex.platform.imdg.api.Imdg; import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.util.Map; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.TestUtils.*; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; public class MoneyMarketSecurityServiceTest extends AbstractServiceTest{ private static final MatcherFactory.Matcher MONEY_MARKET_SECURITY_MATCHER = usingIgnoringFieldsComparator("created", "updated"); diff --git a/clearing-parent/test-clearing/pom.xml b/clearing-parent/test-clearing/pom.xml index cae0c252e..4c1f1dc5e 100644 --- a/clearing-parent/test-clearing/pom.xml +++ b/clearing-parent/test-clearing/pom.xml @@ -51,5 +51,14 @@ org.junit.jupiter junit-jupiter-api + + com.hazelcast + hazelcast-all + 3.12.4 + + + ru.spcex.platform + platform-imdg-api-hazelcast-impl + diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/ImapEvent.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/ImapEvent.java similarity index 98% rename from clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/ImapEvent.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/ImapEvent.java index 44a613cd0..d6b74267b 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/ImapEvent.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/ImapEvent.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.company.utils; +package ru.spcex.clearing.test; import com.hazelcast.core.IMap; import com.hazelcast.map.listener.EntryAddedListener; diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/MatcherFactory.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/MatcherFactory.java similarity index 97% rename from clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/MatcherFactory.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/MatcherFactory.java index bf8c58af3..6b5f60c45 100644 --- a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/MatcherFactory.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/MatcherFactory.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing; +package ru.spcex.clearing.test; import java.util.Arrays; diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/TestUtils.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/TestUtils.java similarity index 98% rename from clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/TestUtils.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/TestUtils.java index e97deebb6..2d542894e 100644 --- a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/TestUtils.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/TestUtils.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing; +package ru.spcex.clearing.test; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -29,8 +29,8 @@ import java.util.concurrent.TimeoutException; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static ru.spcex.clearing.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.platform.messaging.service.Status.Success; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; public class TestUtils { public static final MatcherFactory.Matcher> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(); @@ -77,6 +77,7 @@ public class TestUtils { assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic()); BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest); } + public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) { TopicPartition tp = new TopicPartition(topic, partition); HashMap startOffsets = new HashMap<>(); diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/ImdgTestConfig.java similarity index 98% rename from clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/ImdgTestConfig.java index 9fa010b83..ca50a9d5f 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/ImdgTestConfig.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/ImdgTestConfig.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.securities.config; +package ru.spcex.clearing.test.config; import com.hazelcast.config.*; import com.hazelcast.core.Hazelcast; diff --git a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/KafkaTestConfig.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/KafkaTestConfig.java similarity index 97% rename from clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/KafkaTestConfig.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/KafkaTestConfig.java index 5f54dac64..69665a7f2 100644 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/KafkaTestConfig.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/KafkaTestConfig.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.securities.config; +package ru.spcex.clearing.test.config; import org.apache.kafka.clients.consumer.MockConsumer; import org.apache.kafka.clients.consumer.OffsetResetStrategy; diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/JsonUtil.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/JsonUtil.java similarity index 98% rename from clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/JsonUtil.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/JsonUtil.java index 71efc1b6c..7a64a96b6 100644 --- a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/JsonUtil.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/JsonUtil.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.imdg; +package ru.spcex.clearing.test.json; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryWithJson.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/MatcherFactoryWithJson.java similarity index 98% rename from clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryWithJson.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/MatcherFactoryWithJson.java index ae8a5bbd5..1824063ef 100644 --- a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/imdg/MatcherFactoryWithJson.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/MatcherFactoryWithJson.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.imdg; +package ru.spcex.clearing.test.json; import org.assertj.core.api.Assertions; import org.springframework.test.web.servlet.MvcResult; From 2573b559c5940df58f356d3bc15255fc618a7843 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 7 Apr 2023 18:44:08 +0300 Subject: [PATCH 90/90] =?UTF-8?q?company-service=20ProfileDocumentService?= =?UTF-8?q?=20-=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D0=B2=20?= =?UTF-8?q?account-service=20kafka?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProfileDocumentValidationConfig.java | 23 ++++ .../service/AccountNotificationHelper.java | 20 ++++ .../service/ProfileDocumentService.java | 103 +++++++++++++++--- .../service/ProfileDocumentServiceTest.java | 38 +++++++ .../platform/messaging/domain/Consts.java | 1 + 5 files changed, 170 insertions(+), 15 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java index 7dbbc420a..098c6a550 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 @@ -7,6 +7,7 @@ import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.platform.dictionary.DocumentTypeDictionary; 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.ProfileDocumentNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; import ru.spcex.clearing.validation.common.rules.*; @@ -130,4 +131,26 @@ public class ProfileDocumentValidationConfig { ); }; } + + @Bean("profileDocumentDeleteRequestValidation") + public Function profileDocumentDeleteRequestValidator( + Map> imdgForValidation + ) { + return profileDocumentDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(profileDocumentDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary); + addImdg.accept(IMDGDistributedNames.Map_ProfileDocument); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_ProfileDocument, + ProfileDocument.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RecordNotFound) + ); + }; + } } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java index cfd70c1c3..1dfc41da7 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java @@ -61,4 +61,24 @@ public class AccountNotificationHelper { r.setAccountId(account.getId()); return r; } + + + public CompanyErrors accountTerminationByDocumentNotification(Long companyId) { + Collection accounts = accountMap.getCollectionObjectsBySQL("companyId=" + companyId); + log.trace("Found {} accounts by company {}", accounts.size(), companyId); +// for (Account account : accounts) { +// Collection liabilities = liabilitiesClaimsAssetsMap.getCollectionObjectsBySQL("accountId=" + account.getId()); +// for (LiabilitiesClaimsAssets liability : liabilities) { +// if (liability.getLiabilitiesQuantity() != null && BigDecimal.ZERO.compareTo(liability.getLiabilitiesQuantity()) == 0) { +// return CompanyErrors.CompanyAlreadyHasLiabilities; +// } +// } +// } + log.debug("Sending messages to account-service for {} account", accounts.size()); + for (Account account : accounts) { + Long reqId = kafkaSender.sendRequestToQueue(Consts.ACCOUNT_TERMINATION, createAccountsRequest(companyId, account)); + log.debug("For account[{}] send termination by document request id={}", account.getId(), reqId); + } + return null; + } } \ No newline at end of file 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 b8f9bbdbd..411cfd669 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 @@ -11,9 +11,12 @@ import org.springframework.lang.NonNull; 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.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.service.QueueConsumer; @@ -21,10 +24,14 @@ 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; +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.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; +import java.util.Objects; import java.util.function.Function; @Service @@ -33,29 +40,38 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin private Imdg profileDocumentMap; private Imdg companyMap; private ImdgProvider imdgProvider; - private KafkaSender kafkaReqProducer; + private AccountNotificationHelper accountNotificationHelper; private final Function profileDocumentNewRequestValidator; private final Function profileDocumentUpdateRequestValidator; + private final Function profileDocumentDeleteRequestValidator; private final ValidationHelper validationHelper; private final UserRoleVerification userRoleVerification; + protected IMessageResolver messageResolver; + protected RequestHelper requestHelper; @Autowired public ProfileDocumentService(Consumer kafkaQueue, Producer kafkaProducer, - KafkaSender kafkaReqProducer, ImdgProvider imdgProvider, UserRoleVerification userRoleVerification, @Qualifier("profileDocumentNewRequestValidation") Function profileDocumentNewRequestValidator, @Qualifier("profileDocumentUpdateRequestValidation") Function profileDocumentUpdateRequestValidator, - ValidationHelper validationHelper) { + @Qualifier("profileDocumentDeleteRequestValidation") Function profileDocumentDeleteRequestValidator, + ValidationHelper validationHelper, + IMessageResolver messageResolver, + RequestHelper requestHelper, + AccountNotificationHelper accountNotificationHelper) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; - this.kafkaReqProducer = kafkaReqProducer; + this.accountNotificationHelper = accountNotificationHelper; this.profileDocumentNewRequestValidator = profileDocumentNewRequestValidator; this.profileDocumentUpdateRequestValidator = profileDocumentUpdateRequestValidator; + this.profileDocumentDeleteRequestValidator = profileDocumentDeleteRequestValidator; this.validationHelper = validationHelper; this.userRoleVerification = userRoleVerification; + this.messageResolver = messageResolver; + this.requestHelper = requestHelper.setLogger(log); } @Override @@ -64,11 +80,14 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); callback(ProfileDocumentNewRequest.class) - .setConsumer(this::profileDocumentNew) + .setFunction(this::profileDocumentNew) .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); callback(ProfileDocumentUpdateRequest.class) - .setConsumer(this::profileDocumentUpdate) + .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(); } @@ -100,15 +119,45 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin profileDocument.setLink(profileDocumentNewRequest.getLink()); profileDocumentMap.insert(profileDocument); -// if (profileDocument.getDocumentType().equalsIgnoreCase(DocumentTypes.xcnt.getKey())) { - // todo create request for update and check request for new account (something wrong) -// kafkaReqProducer.sendRequestToQueue(Consts.ACCOUNT_UPDATE, ) -// } + if (DocumentTypes.xcnt.getKey().equalsIgnoreCase(profileDocument.getDocumentType())) { + processXCNT(profileDocument); + } return null; } - @NonNull + private RequestInfoUpdate profileDocumentDelete(BaseRequest deleteRequest) { + log.trace("Start processing CommonDeleteRequest!"); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(deleteRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError( + deleteRequest, profileDocumentDeleteRequestValidator + ); + if (requestInfoUpdate != null) return requestInfoUpdate; + + CommonDeleteRequest profileDocumentDeleteRequest = deleteRequest.getRequestPayload(); + ProfileDocument profileDocument = profileDocumentMap.getSingleObjectByID(profileDocumentDeleteRequest.getId()); + + Company existCompany = profileDocument.getCompanyId() == null ? null : companyMap.getSingleObjectByID(profileDocument.getCompanyId()); + if (existCompany == null) { + log.warn("Company {} not found by profileDocument {}", profileDocument.getCompanyId(), profileDocument.getId()); + return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId()); + } + if (!WorkflowStatus.Active.equalsByKey(existCompany.getWorkflowStatus())) { + log.debug("Company {} not active", profileDocument.getCompanyId()); + return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId()); + } + + profileDocumentMap.delete(profileDocument); + + log.trace("successfully deleted, id {}", profileDocument.getId()); + + return null; + } + + private RequestInfoUpdate profileDocumentUpdate(BaseRequest profileDocumentUpdateRequestBaseRequest) { log.trace("Start processing ProfileDocumentUpdateRequest!"); @@ -124,6 +173,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin ProfileDocumentUpdateRequest profileDocumentUpdateRequest = profileDocumentUpdateRequestBaseRequest.getRequestPayload(); ProfileDocument profileDocument = profileDocumentMap.getSingleObjectByID(profileDocumentUpdateRequest.getId()); + String prevDocType = profileDocument.getDocumentType(); if (profileDocumentUpdateRequest.getCompanyId() != null) profileDocument.setCompanyId(profileDocumentUpdateRequest.getCompanyId()); @@ -164,11 +214,34 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin log.trace("successfully processed, id {}", profileDocument.getId()); -// if (profileDocument.getDocumentType().equalsIgnoreCase(DocumentTypes.xcnt.getKey())) { - // todo if update profileDocument with documentType == XCNT... need send? -// kafkaReqProducer.sendRequestToQueue(Consts.ACCOUNT_UPDATE, ) -// } + if (!Objects.equals(prevDocType, profileDocument.getDocumentType()) && + DocumentTypes.xcnt.getKey().equalsIgnoreCase(profileDocument.getDocumentType())) { + processXCNT(profileDocument); + } return null; } + + protected void processXCNT(ProfileDocument profileDocument) { + Company existCompany = profileDocument.getCompanyId() == null ? null : companyMap.getSingleObjectByID(profileDocument.getCompanyId()); + if (existCompany == null) { + log.warn("Company {} not found by profileDocument {}", profileDocument.getCompanyId(), profileDocument.getId()); + return; + } + if (!WorkflowStatus.Active.equalsByKey(existCompany.getWorkflowStatus())) { + log.warn("Current workflowStatus {} for company {}. Do not termination account.", + existCompany.getWorkflowStatus(), existCompany.getId()); + } + + CompanyErrors hasError = accountNotificationHelper.accountTerminationByDocumentNotification(profileDocument.getCompanyId()); + if (hasError != null) { + log.error("Error at termination account of company {} by document {}: {}", + profileDocument.getCompanyId(), profileDocument.getId(), hasError + "(" + hasError.getId() + ")"); + } + /* todo processXCNT + Дальнейшая обработка документа о расторжении, то есть обновление статусов в company и relation, возможна только после ответа об успешном обновлении статуса в account. + 1.2. Обновить статус в бизнес-объекте company [profileDocument.companyId=company.id] согласно описанию с тегом "При расторжении". + 1.3. Обновить статус в бизнес-объекте relation [profileDocument.companyId=relation.consumerId] согласно описанию с тегом "При расторжении". + */ + } } diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java index ce47319fa..f7450e798 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ProfileDocumentServiceTest.java @@ -3,6 +3,7 @@ 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; @@ -21,6 +22,7 @@ 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.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.test.MatcherFactory; @@ -47,6 +49,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; BeanConfiguration.class, ValidationConfig.class, ProfileDocumentService.class, + AccountNotificationHelper.class, ProfileDocumentValidationConfig.class, KafkaTestConfig.class, ImdgTestConfig.class}) @@ -56,6 +59,7 @@ class ProfileDocumentServiceTest { private static final int PARTITION = 0; private static final String TOPIC_DESTINATION_PROFILE_DOCUMENT_NEW = Consts.DESTINATION_PROFILE_DOCUMENT_NEW; private static final String TOPIC_DESTINATION_PROFILE_DOCUMENT_UPDATE = Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE; + private static final String TOPIC_DESTINATION_PROFILE_DOCUMENT_DELETE = Consts.DESTINATION_PROFILE_DOCUMENT_DELETE; private static final Long ID = currentID.getAndIncrement(); @Autowired @@ -220,4 +224,38 @@ class ProfileDocumentServiceTest { // predictableProfileDocument.setId(resultUpdate.getId()); PROFILE_DOCUMENT_MATCHER.assertMatch(resultUpdate, predictableProfileDocument); } + + + @Test + void deleteProfileDocument() { + //ARRANGE + ProfileDocument existsProfileDocument = new ProfileDocument(); + existsProfileDocument.setId(PROFILE_DOCUMENT_ID); + existsProfileDocument.setCompanyId(COMPANY_ID); + existsProfileDocument.setDocumentType(TEST_DOCUMENT_TYPE_ID); + existsProfileDocument.setIssueDate(LocalDate.now()); + existsProfileDocument.setIssuePlace("place"); + existsProfileDocument.setIssuer("issuer"); + existsProfileDocument.setIssuerCode("issuerCode"); + existsProfileDocument.setName("name"); + existsProfileDocument.setNumber("number"); + existsProfileDocument.setPlace("place"); + existsProfileDocument.setValidFromDate(LocalDate.now()); + existsProfileDocument.setValidToDate(LocalDate.now().plus(1, ChronoUnit.DAYS)); + existsProfileDocument.setLink("link"); + profileDocumentMap.insert(existsProfileDocument); + + CommonDeleteRequest profileDocumentDeleteRequest = new CommonDeleteRequest(); + profileDocumentDeleteRequest.setId(PROFILE_DOCUMENT_ID); + + //ACT + String jsonString = getJsonStringForUPDATE(profileDocumentDeleteRequest, ID); + + addRecordToKafka((MockConsumer) profileDocumentService.getConsumer(), TOPIC_DESTINATION_PROFILE_DOCUMENT_DELETE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + ProfileDocument resultUpdate = profileDocumentMap.getSingleObjectByID(PROFILE_DOCUMENT_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 1d3809845..fddd74586 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 @@ -60,6 +60,7 @@ public interface Consts { String DESTINATION_RELATION_UPDATE = "relation-update"; String DESTINATION_PROFILE_DOCUMENT_NEW = "profile-document-new"; String DESTINATION_PROFILE_DOCUMENT_UPDATE = "profile-document-update"; + String DESTINATION_PROFILE_DOCUMENT_DELETE = "profile-document-delete"; String DESTINATION_SDF08_NEW = "s-df-08-new"; String DESTINATION_SDF02_NEW = "s-df-02-new";