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/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/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/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/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..675046e44 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/company/CompanyNewAction.java @@ -0,0 +1,85 @@ +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 = "TRDC") + @JsonProperty + private String companySymbol; + @ApiModelProperty(value = "Значение реквизита", example = "COMPANYSYMBOL_VALUE-123") + @JsonProperty + private String companySymbolValue; + @ApiModelProperty(value = "Наименование статуса", example = "ACTV") + @JsonProperty + private String workflowStatus; + + + @Override + public CompanyNewRequest toRequest() { + CompanyNewRequest request = new CompanyNewRequest(); + request.setShortName(this.shortName); + request.setFullName(this.fullName); + request.setCompanySymbol(this.companySymbol); + request.setCompanySymbolValue(this.companySymbolValue); + request.setWorkflowStatus(this.workflowStatus); + 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 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 String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } +} 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/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 %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/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() 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 1f21495fd..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 @@ -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,30 +28,51 @@ 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 - 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()); + if (appendUserId) { + request.setUserId(currentUserId()); + } //сохраняет данные о запросе в хранилище saveRequestToStorage(destination, request); Future send = kafka.send(new ProducerRecord<>(destination, request)); 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/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..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 @@ -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.test.json.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 0e04e9aad..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 @@ -55,13 +55,13 @@ 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.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.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.test.json.JsonUtil.readValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.MatcherFactoryWithJson.usingIgnoringFieldsComparatorForClass; @ContextConfiguration(classes = { @@ -92,7 +92,7 @@ import static ru.spcex.clearing.backendapi.controller.utils.MatcherFactory.using BankAccountController.class, //company CompanyRoleSetController.class, - DeleteCompanyController.class, + CompanyController.class, EditClearingMemberCategoryController.class, EditCompanyInfoController.class, EditCompanySymbolController.class, @@ -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 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/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..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.backendapi.controller.utils.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 9c868d3b8..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.backendapi.controller.utils.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 b503dfaf8..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.backendapi.controller.utils.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 7368196d8..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.backendapi.controller.utils.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 5f51b0b1c..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.backendapi.controller.utils.JsonUtil.writeValue; +import static ru.spcex.clearing.test.json.JsonUtil.writeValue; class EditContactControllerTest extends AbstractControllerTest { private static final String REST_URL = "/contacts/"; @@ -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()); 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..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.backendapi.controller.utils.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 708cb12c3..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.backendapi.controller.utils.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 83d4ebcef..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.backendapi.controller.utils.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 1689c06ba..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.backendapi.controller.utils.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 85ac5f57b..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.backendapi.controller.utils.JsonUtil.readValue; -import static ru.spcex.clearing.backendapi.controller.utils.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 c7759e880..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.backendapi.controller.utils.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 688a0b946..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.backendapi.controller.utils.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/securities/CudMoneyMarketSecurityControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/securities/CudMoneyMarketSecurityControllerTest.java index 4c9656656..13a606443 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/securities/CudMoneyMarketSecurityControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/securities/CudMoneyMarketSecurityControllerTest.java @@ -28,12 +28,12 @@ class CudMoneyMarketSecurityControllerTest extends AbstractControllerTest { MoneyMarketSecurityNewAction moneyMarketSecurityNewAction = new MoneyMarketSecurityNewAction(); moneyMarketSecurityNewAction.setStartDate(LocalDate.now()); moneyMarketSecurityNewAction.setEndDate(LocalDate.now()); - moneyMarketSecurityNewAction.setNominalValue(2D); + moneyMarketSecurityNewAction.setNominalValue(new BigDecimal("2.6")); moneyMarketSecurityNewAction.setNominalCurrency("nominal"); moneyMarketSecurityNewAction.setInstrumentType("status"); moneyMarketSecurityNewAction.setFullName("fname"); moneyMarketSecurityNewAction.setSecuritySymbol("sname"); - moneyMarketSecurityNewAction.setLotSize(3D); + moneyMarketSecurityNewAction.setLotSize(new BigDecimal("3.5")); //ACT and ASSERT checkAddingByRestApi(REST_URL, moneyMarketSecurityNewAction); @@ -53,11 +53,11 @@ class CudMoneyMarketSecurityControllerTest extends AbstractControllerTest { moneyMarketSecurityUpdateAction.setId(id); moneyMarketSecurityUpdateAction.setStartDate(LocalDate.now()); moneyMarketSecurityUpdateAction.setEndDate(LocalDate.now()); - moneyMarketSecurityUpdateAction.setNominalValue(2D); + moneyMarketSecurityUpdateAction.setNominalValue(new BigDecimal("2.6")); moneyMarketSecurityUpdateAction.setNominalCurrency("nominal"); moneyMarketSecurityUpdateAction.setInstrumentType("status"); moneyMarketSecurityUpdateAction.setFullName("fname"); - moneyMarketSecurityUpdateAction.setLotSize(3D); + moneyMarketSecurityUpdateAction.setLotSize(new BigDecimal("3.5")); MoneyMarketSecurity moneyMarketSecurity = getMoneyMarketSecurity(id); //ACT and ASSERT 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..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.backendapi.controller.utils.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 8c6fd458b..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.backendapi.controller.utils.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/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/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/TestUtils.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/TestUtils.java deleted file mode 100644 index 45091310f..000000000 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/utils/TestUtils.java +++ /dev/null @@ -1,95 +0,0 @@ -package ru.spcex.clearing.backendapi.controller.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.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; - } - } -} 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/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/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..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,13 +2,15 @@ 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; /** * Инструменты *

* DB table: SECURITY **/ -public class Security extends BusinessObject { +public class Security extends BusinessObject implements WithWorkflowStatus, WithInstrumentType { private static final long serialVersionUID = ConstSerializable.serialVersionUID; private String instrumentType; 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..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 @@ -1,11 +1,11 @@ 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), + AccountNotActive(5415L), + CompanyNotActive(5411L), FinancialObligationNotSatisfied(4L), ; private final Long id; 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/clearing-validation/pom.xml b/clearing-parent/clearing-validation/pom.xml new file mode 100644 index 000000000..60ad3b00b --- /dev/null +++ b/clearing-parent/clearing-validation/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + + clearing-validation + clearing-validation + Clearing-module, 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 + + + ru.spcex.platform + platform-messaging + + + \ No newline at end of file diff --git a/clearing-parent/clearing-validation/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 new file mode 100644 index 000000000..4077b07c4 --- /dev/null +++ b/clearing-parent/clearing-validation/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/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java new file mode 100644 index 000000000..f8aef7bf6 --- /dev/null +++ b/clearing-parent/clearing-validation/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); + } +} 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 new file mode 100644 index 000000000..9a3ad0c24 --- /dev/null +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/ValidationHelper.java @@ -0,0 +1,58 @@ +package ru.spcex.clearing.validation.common; + +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 ru.spcex.platform.utils.validation.IValidator; + +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +public class ValidationHelper { + private final static Logger log = LoggerFactory.getLogger(ValidationHelper.class); + + private IMessageResolver messageResolver; + + public ValidationHelper(IMessageResolver messageResolver) { + Objects.requireNonNull(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); + Optional validationError = validator.tillFirstError(); + if (validationError.isPresent()) { + String errorMsg = messageResolver.resolve(validationError.get()); + 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) + .setMessage(errorMsg); + } + } + return null; + } + + + public IMessageResolver getMessageResolver() { + return messageResolver; + } + + public void setMessageResolver(IMessageResolver messageResolver) { + this.messageResolver = messageResolver; + } +} diff --git a/clearing-parent/clearing-validation/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 new file mode 100644 index 000000000..a22834156 --- /dev/null +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DateNotBeforeRule.java @@ -0,0 +1,62 @@ +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.time.LocalDate; +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка поля с LocalDate. Условие проверки: поверяемая дата >= текущая дата + * @param Класс проверяемого объекта + */ +public record DateNotBeforeRule( + String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastDate, + boolean required +) implements IValidationRule> { + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемой даты + * @param required Флаг обязательности поля + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorTaskForPastDate Ошибка, которая будет возвращена, если проверяемая дата меньше текущей + * @param Класс проверяемого объекта + */ + public static DateNotBeforeRule instance(String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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-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 new file mode 100644 index 000000000..30c25318b --- /dev/null +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/DictionaryPresentRule.java @@ -0,0 +1,123 @@ +package ru.spcex.clearing.validation.common.rules; + +import ru.clearing.platform.dictionary.AbstractDictionary; +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.IErrorEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorWrongDictionaryValue, + boolean required, + Function[] additionalChecks) implements IValidationRule> { + + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param dictionaryName Название словаря (см. IMDGDistributedNames) + * @param dictionaryClass Класс словаря (классы *Dictionary.class) + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorWrongDictionaryValue Ошибка, которая будет возвращена, если поле не найдено в словаре + * @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, + Function... additionalChecks) { + return new DictionaryPresentRule<>(fieldName, + getter, + dictionaryName, + dictionaryClass, + errorEmptyRequiredValue, + errorWrongDictionaryValue, + required, + additionalChecks); + } + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param dictionaryName Название словаря (см. IMDGDistributedNames) + * @param dictionaryClass Класс словаря (классы *Dictionary.class) + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorWrongDictionaryValue Ошибка, которая будет возвращена, если поле не найдено в словаре + * @param additionalChecks Дополнительные проверки, связанные с этим полем + * @param Класс проверяемого объекта + * @param Класс словаря + */ + @SafeVarargs + public static DictionaryPresentRule instance(String fieldName, + Function getter, + String dictionaryName, + Class dictionaryClass, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorWrongDictionaryValue, + Function... additionalChecks) { + return new DictionaryPresentRule<>(fieldName, + getter, + dictionaryName, + dictionaryClass, + errorEmptyRequiredValue, + errorWrongDictionaryValue, + true, + additionalChecks); + } + + @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); + } + D dictionaryFromMap = fromMap.iterator().next(); + 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(); + } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + " - " + dictionaryName + "}"; + } +} diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java new file mode 100644 index 000000000..169e5589f --- /dev/null +++ b/clearing-parent/clearing-validation/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.IErrorEnumId; +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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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, startDtFieldName, endDtFieldName); + return Optional.empty(); + } +} diff --git a/clearing-parent/clearing-validation/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 new file mode 100644 index 000000000..5b503aedf --- /dev/null +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EnumPresentRule.java @@ -0,0 +1,77 @@ +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.IEnumKey; +import ru.spcex.platform.utils.enumeration.IErrorEnumId; +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, + IErrorEnumId errorWrongEnumValue, + IErrorEnumId errorEmptyRequiredValue) implements IValidationRule> { + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param enumValues Значения из проверяемого множества (Enum.values()) + * @param errorWrongEnumValue Ошибка, которая будет возвращена, если поле не найдено в Enum + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param required Флаг обязательности + * @param Класс проверяемого объекта + * @param Enum + */ + public static EnumPresentRule instance(String fieldName, + Function getter, + E[] enumValues, + boolean required, + 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); + } + + /** + * @param fieldName Название поля + * @param getter Метод получения проверяемого значения + * @param enumValues Значения из проверяемого множества (Enum.values()) + * @param errorWrongEnumValue Ошибка, которая будет возвращена, если поле не найдено в Enum + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param Класс проверяемого объекта + * @param Enum + */ + public static EnumPresentRule instance(String fieldName, + Function getter, + E[] enumValues, + IErrorEnumId errorWrongEnumValue, + IErrorEnumId 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); + } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + "}"; + } +} 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 new file mode 100644 index 000000000..eaa468190 --- /dev/null +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/FieldRequiredRule.java @@ -0,0 +1,63 @@ +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; + +/** + * Проверка обязательности поля (not null) + * + * @param fieldName Название поля + * @param getter Метод получения значения + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param additionalChecks Дополнительные проверки, связанные с этим полем + * @param Класс проверяемого объекта + * @param Класс проверяемого значения + */ +public record FieldRequiredRule( + String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredValue, + Function[] additionalChecks +) implements IValidationRule> { + + /** + * @param fieldName Название поля + * @param getter Метод получения значения + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param additionalChecks Дополнительные проверки, связанные с этим полем + * @param Класс проверяемого объекта + * @param Класс проверяемого значения + */ + @SafeVarargs + 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, additionalChecks); + } + + @Override + public Optional validate(ImdgValidationContext context) { + 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(); + } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + "}"; + } +} diff --git a/clearing-parent/clearing-validation/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 new file mode 100644 index 000000000..1c6abcfaf --- /dev/null +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/IdPresentRule.java @@ -0,0 +1,111 @@ +package ru.spcex.clearing.validation.common.rules; + +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.IErrorEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка наличия связанного по Id объекта в базе + * @param Класс проверяемого объекта + * @param Класс связанного объекта + */ +public record IdPresentRule( + String fieldName, + Function idGetter, + String mapName, + Class mapClass, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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) { + IErrorEnumId validationError = additionalCheck.apply(fromMap); + if (validationError != null) + return of(validationError, fieldName); + } + return empty(); + } + + @Override + public String ruleName() { + return getClass().getSimpleName() + "{" + fieldName + "}"; + } +} diff --git a/clearing-parent/clearing-validation/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 new file mode 100644 index 000000000..a5dcdd328 --- /dev/null +++ b/clearing-parent/clearing-validation/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(); + } +} diff --git a/clearing-parent/clearing-validation/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 new file mode 100644 index 000000000..7ab42a96c --- /dev/null +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/TimeNotBeforeRule.java @@ -0,0 +1,62 @@ +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.time.LocalTime; +import java.util.Optional; +import java.util.function.Function; + +/** + * Проверка поля с LocalTime. Условие проверки: проверяемое время >= текущее время + * @param Класс проверяемого объекта + */ +public record TimeNotBeforeRule( + String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId errorTaskForPastTime, + boolean required +) implements IValidationRule> { + + /** + * @param fieldName Название поля класса, используется для передачи ошибки + * @param getter Метод получения проверяемого времени + * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое + * @param errorTaskForPastTime Ошибка, которая будет возвращена, если проверяемое время меньше текущего + * @param required Флаг обязательности поля + * @param Класс проверяемого объекта + */ + public static TimeNotBeforeRule instance(String fieldName, + Function getter, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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, + IErrorEnumId errorEmptyRequiredValue, + IErrorEnumId 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/company-service/pom.xml b/clearing-parent/company-service/pom.xml index a34291ee8..3143aecaa 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-validation + org.springframework.boot spring-boot-starter @@ -41,6 +53,11 @@ spring-boot-starter-test test + + ru.spcex.clearing + test-clearing + test + 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..d0189af7a --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/BeanConfiguration.java @@ -0,0 +1,33 @@ +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.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; + +@Configuration +public class BeanConfiguration { + @Bean + public IMessageResolver messageResolver() { + return new SimpleMessageResolver(); + } + + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public RequestHelper requestHelper(IMessageResolver messageResolver) { + return new RequestHelper(messageResolver); + } + + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) + 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/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 new file mode 100644 index 000000000..d1c44aa66 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClearingMemberCategoryValidationConfig.java @@ -0,0 +1,120 @@ +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.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); + addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); + 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), + DictionaryPresentRule.instance("clearingMemberCategory", + ClearingMemberCategoryNewRequest::getClearingMemberCategory, + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CategoryNotFound)); + }; + } + + @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_ClearingCategoryDictionary); + 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(), + false, + CompanyErrors.WrongFieldValue, + CompanyErrors.RequiredFieldEmpty), + DictionaryPresentRule.instance("clearingMemberCategory", + ClearingMemberCategoryUpdateRequest::getClearingMemberCategory, + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue, + false)); + }; + } + + @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/CompanySymbolValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java new file mode 100644 index 000000000..8c747cfef --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanySymbolValidationConfig.java @@ -0,0 +1,107 @@ +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.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; +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 CompanySymbolOfSymbolNewRequestNotExistRule() + ); + }; + } + + @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/config/validation/CompanyValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java new file mode 100644 index 000000000..b31127875 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/CompanyValidationConfig.java @@ -0,0 +1,193 @@ +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.*; +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; +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_CompanySymbols); + addImdg.accept(IMDGDistributedNames.Map_CompanySymbolDictionary); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_Company); + 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), + 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), + new CompanySymbolNotExistRule() + ); + }; + } + + @Bean("companyUpdateRequestValidator") + 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) + ); + }; + } + + + @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); + 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", + 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/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/ProfileDocumentValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java new file mode 100644 index 000000000..098c6a550 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java @@ -0,0 +1,156 @@ +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.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.*; +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) + ); + }; + } + + @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) + ); + }; + } + + @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/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..a076fa999 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java @@ -0,0 +1,56 @@ +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; +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; +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_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); + addImdg.accept(IMDGDistributedNames.Map_ContactTypeDictionary, ContactTypeDictionary.class); + 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); + addImdg.accept(IMDGDistributedNames.Map_AllowedDictionary, AllowedDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class); + + + 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/error/CompanyErrors.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java new file mode 100644 index 000000000..d36d2104f --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java @@ -0,0 +1,37 @@ +package ru.spcex.clearing.company.error; + +import ru.spcex.platform.utils.enumeration.IErrorEnumId; + +public enum CompanyErrors implements IErrorEnumId { + GeneralError(3000L), // Общая ошибка модуля company-service + UserVerifyDenial(3001L), // 'Нет прав на проведение данной операции + + RequiredFieldEmpty(3002L), // Не заданы обязательные поля %s. + DictionaryNotFound(3003L), // Запись с идентификатором %s в справочнике %s не найдена. + WrongFieldValue(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. + CompanyAlreadyHasLiabilities(3018L), // У компании %s присутствуют обязательства. + CompanyWithCompanySymbolAlreadyExist(3019L), // Компания с %s = %s уже создана" (где первый %s - companySymbol, второй %s - companySymbolValue) + EditCompanySymbols(3020L), // Тип реквизита компании %s не может быть изменен. + EditContactType(3021L) // Тип контакта компании %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/AccountNotificationHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java new file mode 100644 index 000000000..1dfc41da7 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/AccountNotificationHelper.java @@ -0,0 +1,84 @@ +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; + } + + + 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/ClearingMemberCategoryService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java index 869049fe8..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 @@ -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; @@ -15,19 +16,42 @@ 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.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.validation.IValidator; + +import java.util.function.Function; @Service public class ClearingMemberCategoryService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final Imdg clearingMemberCategoryMap; + private final Function clearingMemberCategoryNewRequestValidator; + 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) { + public ClearingMemberCategoryService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, + @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.clearingMemberCategoryNewRequestValidator = clearingMemberCategoryNewRequestValidator; + this.clearingMemberCategoryUpdateRequestValidator = clearingMemberCategoryUpdateRequestValidator; + this.clearingMemberCategoryDeleteRequestValidator = clearingMemberCategoryDeleteRequestValidator; + this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; } @Override @@ -44,19 +68,35 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init init(); } - private void clearingMemberCategoryNew(BaseRequest userRequest) { + private RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { + log.debug("ClearingMemberCategoryNewRequest received {}", userRequest.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); - 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 = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clearingMemberCategoryUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + log.debug("ClearingMemberCategoryUpdateRequest received"); ClearingMemberCategory clearingMemberCategory = clearingMemberCategoryMap.getSingleObjectByID(req.getId()); @@ -64,12 +104,22 @@ 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 = 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()); ClearingMemberCategory clearingMemberCategory = clearingMemberCategoryMap.getSingleObjectByID(req.getId()); clearingMemberCategoryMap.delete(clearingMemberCategory); + + return null; } } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java index 953bd35b8..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 @@ -6,59 +6,99 @@ 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.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.validation.IValidator; + +import java.time.Instant; +import java.util.function.Function; @Service public class 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) { + ImdgProvider imdgProvider, CompanyService companyService, + RequestHelper requestHelper, ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, + @Qualifier("CompanyInfoUpdateRequestValidator") + Function companyInfoUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); -// this.companyInfoMap = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyInfo, CompanyInfo.class); + this.companyService = companyService; this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; + this.companyInfoUpdateRequestValidator = companyInfoUpdateRequestValidator; + this.requestHelper = requestHelper.setLogger(log); } @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"); -// CompanyInfo companyInfo = companyInfoMap.getSingleObjectByID(req.getId()); - 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()); -// companyInfoMap.update(companyInfo); - companyMap.update(company); - log.debug("successfully processed, id {}", companyInfo.getId()); + public RequestInfoUpdate companyInfoUpdate(BaseRequest companyInfoReq) { + CompanyInfoUpdateRequest req = companyInfoReq.getRequestPayload(); + log.debug("{} received", req.getClass().getSimpleName()); + { // Валидация, ValidationException + 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()); + 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()); + 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()); + + company.setUpdated(Instant.now()); + companyMap.update(company); + 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/CompanyRoleSetService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java new file mode 100644 index 000000000..2af7a358c --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java @@ -0,0 +1,136 @@ +package ru.spcex.clearing.company.service; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.company.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.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 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, + RequestHelper requestHelper, + ValidationHelper validationHelper, + UserRoleVerification userRoleVerification +// @Qualifier("CompanyRoleSetRequestValidator") +// Function companyNewRequestValidator, + ) { + super(kafkaQueue, kafkaProducer); + this.imdgProvider = imdgProvider; + 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 + 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(); + } + + private RequestInfoUpdate createCompanyRoleSet(BaseRequest companyRoleNewRequestBaseRequest) throws ValidationException { + CompanyRoleSetNewRequest req = companyRoleNewRequestBaseRequest.getRequestPayload(); + log.debug("companyroleset-new request received, BaseRequest.id = {}", companyRoleNewRequestBaseRequest.getId()); + { // Валидация, ValidationException + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyRoleNewRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; +// 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 + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyRoleSetDeleteRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + 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/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..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 @@ -6,40 +6,292 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +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.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; + +import java.time.Instant; +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 Imdg companyMap; + private final RequestHelper requestHelper; + private final ImdgProvider imdgProvider; + private final ImdgId idSequence; + protected UserRoleVerification userRoleVerification; + + private ValidationHelper validationHelper; + private Function companyNewRequestValidator; + private Function companyUpdateRequestValidator; + private Function companyDeleteRequestValidator; + + protected CompanySymbolService companySymbolService; + protected AccountNotificationHelper accountNotification; + protected RelationHelper relationHelper; @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider) { + ImdgProvider imdgProvider, + RequestHelper requestHelper, + ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, + @Qualifier("companyNewRequestValidator") + Function companyNewRequestValidator, + @Qualifier("companyUpdateRequestValidator") + Function companyUpdateRequestValidator, + @Qualifier("CompanyDeleteRequestValidator") + Function companyDeleteRequestValidator, + + CompanySymbolService companySymbolService, + AccountNotificationHelper accountNotification, + RelationHelper relationHelper + ) { super(kafkaQueue, kafkaProducer); - this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.imdgProvider = imdgProvider; + this.requestHelper = requestHelper.setLogger(log); + + 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; } @Override public void afterPropertiesSet() { 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)) + .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); + callback(CompanyNewRequest.class) + .setConsumer(request -> requestHelper.requestFunction(this::updateCompany, request)) + .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); init(); } - 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 synchronized RequestInfoUpdate createCompany(BaseRequest companyNewRequestBaseRequest) throws ValidationException { + CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload(); + log.debug("company-new request received, BaseRequest.id = {}", companyNewRequestBaseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyNewRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(companyNewRequestBaseRequest, companyNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + 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()); + + 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()); + + 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; } + + + private synchronized RequestInfoUpdate updateCompany(BaseRequest companyUpdateRequestBaseRequest) throws ValidationException { + CompanyNewRequest updateRequest = companyUpdateRequestBaseRequest.getRequestPayload(); + { // Валидация, + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyUpdateRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(companyUpdateRequestBaseRequest, companyUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + 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()); + } + + 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())) { + relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + } else { + log.trace("Status was not changed"); + } + } else { + log.trace("Null new WorkflowStatus"); + } + companyMap.update(company); + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + 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()); + } + if (CompanySymbol.CLRC.equalsByKey(companySymbol.getCompanySymbol())) { + company.setClearingCode(companySymbol.getCompanySymbolValue()); + } + 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 { + log.trace("No need update company {} by changed companySymbols {}", + companySymbol.getCompanyId(), companySymbol.getCompanySymbol()); + } + } + + /** + * Блокировка компании + * + * @param companyBlockRequestBaseRequest + * @return + */ + private synchronized RequestInfoUpdate deleteCompany(BaseRequest companyBlockRequestBaseRequest) throws ValidationException { + CommonDeleteRequest request = companyBlockRequestBaseRequest.getRequestPayload(); + log.debug("CommonDeleteRequest (block request) received id = {}", request.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyBlockRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(companyBlockRequestBaseRequest, companyDeleteRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + 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()); + + String prevStatus = company.getWorkflowStatus(); + company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); + + relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + log.debug("Update company.id={}", company.getId()); + companyMap.update(company); + + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + return null; + } + } 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..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 @@ -7,44 +7,176 @@ 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 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 companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbolsTMap.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 companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbols = companySymbolsTMap.getSingleObjectByID(req.getId()); +// companySymbols.setCompanySymbol(req.getCompanySymbol()); по ТЗ не должен менятся при обновлении + companySymbols.setCompanySymbolValue(req.getCompanySymbolValue()); + companySymbolsTMap.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 CompanySymbols createCompanySymbol(ImdgTransaction transaction, 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); + if (transaction == null) { + 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); + } + return newSymbol; } } 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..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 @@ -6,44 +6,96 @@ 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.util.security.UserRoleVerification; +import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.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; + private final UserRoleVerification userRoleVerification; @Autowired - public ContactService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider) { + 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; } @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 = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return 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 = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return 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/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..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 @@ -6,33 +6,72 @@ 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.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; +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 public class ProfileDocumentService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); 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) { + ImdgProvider imdgProvider, + UserRoleVerification userRoleVerification, + @Qualifier("profileDocumentNewRequestValidation") Function profileDocumentNewRequestValidator, + @Qualifier("profileDocumentUpdateRequestValidation") Function profileDocumentUpdateRequestValidator, + @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 @@ -41,20 +80,30 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); callback(ProfileDocumentNewRequest.class) - .setConsumer(this::newProfileDocument) + .setFunction(this::profileDocumentNew) .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); + callback(ProfileDocumentUpdateRequest.class) + .setFunction(this::profileDocumentUpdate) + .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::profileDocumentDelete) + .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_DELETE, callbacks::put); init(); } @NonNull - private void newProfileDocument(BaseRequest profileDocumentNewRequestBaseRequest) { + private RequestInfoUpdate profileDocumentNew(BaseRequest profileDocumentNewRequestBaseRequest) { log.trace("Start processing ProfileDocumentNewRequest!"); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentNewRequestBaseRequest); + if (requestInfoUpdate != null) return 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 +118,130 @@ 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 (DocumentTypes.xcnt.getKey().equalsIgnoreCase(profileDocument.getDocumentType())) { + processXCNT(profileDocument); } + + return null; + } + + 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!"); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentUpdateRequestBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError( + profileDocumentUpdateRequestBaseRequest, + profileDocumentUpdateRequestValidator + ); + if (requestInfoUpdate != null) return requestInfoUpdate; + + ProfileDocumentUpdateRequest profileDocumentUpdateRequest = profileDocumentUpdateRequestBaseRequest.getRequestPayload(); + ProfileDocument profileDocument = profileDocumentMap.getSingleObjectByID(profileDocumentUpdateRequest.getId()); + + String prevDocType = profileDocument.getDocumentType(); + 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 (!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/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/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..f134ec949 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java @@ -0,0 +1,97 @@ +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; +import ru.spcex.clearing.platform.messaging.service.Status; +import ru.spcex.platform.utils.enumeration.EnumMessage; +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; + +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 Logger log = LoggerFactory.getLogger(getClass()); + 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); + 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 { + 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 + ? 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 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, IErrorEnumId error, Object ... args) { + return makeErrorResponse(request, new EnumMessage(error, args)); + } + + public interface RequestCommand { + RequestInfoUpdate command(T arg) throws ClearingBaseException; + } + + public RequestHelper setLogger(Logger log) { + if (log == null) return this; + this.log = log; + return this; + } +} 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..b2d477732 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/validation/CompanySymbolNotExistRule.java @@ -0,0 +1,41 @@ +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.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.Optional; + +/** + * Проверка наличия компании с переданными в запросе companySymbol и companySymbolCode (реквизиты) + */ +public class CompanySymbolNotExistRule implements IValidationRule> { + @Override + public Optional 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(); + 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/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()); + } +} 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..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 @@ -13,43 +13,56 @@ 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.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; -import ru.spcex.clearing.company.utils.MatcherFactory.Matcher; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.ClearingMemberCategoryValidationConfig; +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.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 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 org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, ClearingMemberCategoryService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + ClearingMemberCategoryValidationConfig.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; 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 @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg memberCategoryImdg; @Captor @@ -57,22 +70,48 @@ class ClearingMemberCategoryServiceTest { @SpyBean private MockProducer mockProducer; + private long COMPANY_ID; + 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.setWorkflowStatus(WorkflowStatus.Active.getKey()); + COMPANY_ID = companyImdg.insert(TEST_COMPANY); + + clearingCategoryDictionary = new ClearingCategoryDictionary(); + clearingCategoryDictionary.setCode(CLEARING_CATEGORY_DICT_CODE); + clearingCategoryDictionaryImdg.insert(clearingCategoryDictionary); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } @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); @@ -82,6 +121,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); } @@ -95,28 +135,29 @@ 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.setClearingMemberCategory("0000"); + existsClearingMemberCategory.setCompanyId(COMPANY_ID); + Long id = memberCategoryImdg.insert(existsClearingMemberCategory); ClearingMemberCategoryUpdateRequest memberCategoryUpdateRequest = new ClearingMemberCategoryUpdateRequest(); - memberCategoryUpdateRequest.setId(ID); + memberCategoryUpdateRequest.setId(id); memberCategoryUpdateRequest.setClearingMemberCategory(clearingMemberCategory); ClearingMemberCategory predictableClearingMemberCategory = new ClearingMemberCategory(); - predictableClearingMemberCategory.setId(ID); + predictableClearingMemberCategory.setCompanyId(COMPANY_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); } @@ -130,20 +171,19 @@ 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.setClearingMemberCategory(clearingMemberCategory); + 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); 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..f6c22a2e2 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,26 +14,46 @@ 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.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; -import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.clearing.platform.dictionary.*; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; +import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.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.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 ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanyInfoService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + CompanyValidationConfig.class, + CompanySymbolValidationConfig.class, + + CompanyService.class, + CompanyValidationConfig.class, + ValidationConfig.class, + CompanySymbolService.class, + AccountNotificationHelper.class, + RelationHelper.class, + BeanConfiguration.class, + + KafkaTestConfig.class, + ImdgTestConfig.class}) class CompanyInfoServiceTest { public static final MatcherFactory.Matcher COMPANY_INFO_MATCHER = usingIgnoringFieldsComparator(); @@ -44,7 +64,7 @@ class CompanyInfoServiceTest { CompanyInfoService companyInfoService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg companyImdg; @Captor @@ -56,6 +76,26 @@ class CompanyInfoServiceTest { private void init() { hazelcastServiceTest.waitAvailable(); companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.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"); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); + } + + private void putToDictionary(String mapName, D object, String code) { + Imdg dMap = (Imdg) hazelcastServiceTest.getImdg(mapName, object.getClass()); + object.setId(2L); + object.setCode(code); + object.setName("name of " + code); + dMap.insert(object); } /** @@ -63,13 +103,13 @@ class CompanyInfoServiceTest { * Тест проверяет обновление сущности {@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
@@ -94,18 +134,19 @@ class CompanyInfoServiceTest { 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"); @@ -114,13 +155,13 @@ class CompanyInfoServiceTest { 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 b8cd3e7e2..1eb67af79 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,40 +14,67 @@ 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.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; -import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.clearing.platform.dictionary.CompanySymbolDictionary; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; +import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; +import ru.spcex.clearing.company.error.CompanyErrors; 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; +import java.util.Map; -import static ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanyService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + CompanyValidationConfig.class, + ValidationConfig.class, + CompanySymbolService.class, + AccountNotificationHelper.class, + RelationHelper.class, + + CompanySymbolService.class, + CompanySymbolValidationConfig.class, + + KafkaTestConfig.class, + ImdgTestConfig.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; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg companyImdg; + private Imdg companySymbolsImdg; + private Imdg workflowStatusDictionaryImdg; @Captor private ArgumentCaptor producerRecord; @@ -58,6 +85,37 @@ 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(); + ws1.setId(1L); + ws1.setCode(WorkflowStatus.Active.getKey()); + ws1.setName("Active"); + workflowStatusDictionaryImdg.insert(ws1); + WorkflowStatusDictionary ws2 = new WorkflowStatusDictionary(); + ws2.setId(2L); + ws2.setCode(WorkflowStatus.Blocked.getKey()); + ws2.setName("Blocked"); + workflowStatusDictionaryImdg.insert(ws2); + + Imdg companySymbolDictionaryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class); + { + CompanySymbolDictionary cSymbol = new CompanySymbolDictionary(); + cSymbol.setId(11L); + cSymbol.setCode(CompanySymbol.CLRC.getKey()); + cSymbol.setName(CompanySymbol.CLRC.getKey()); + cSymbol.setShortname(" CLRC key"); + companySymbolDictionaryImdg.insert(cSymbol); + CompanySymbolDictionary cioSymbol = new CompanySymbolDictionary(); + cioSymbol.setId(22L); + cioSymbol.setCode(CompanySymbol.CIO.getKey()); + cioSymbol.setName(CompanySymbol.CIO.getKey()); + companySymbolDictionaryImdg.insert(cioSymbol); + } + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } /** @@ -69,8 +127,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(); @@ -83,7 +143,87 @@ class CompanyServiceTest { //ASSERT waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); - Company resultDeleting = companyImdg.getSingleObjectByID(ID); - Assertions.assertNull(resultDeleting); + //Company resultDeleting = companyImdg.getSingleObjectByID(ID); + Company resultDeleting = companyImdg.getSingleObjectBySQL("id=" + ID); + Assertions.assertEquals(WorkflowStatus.Blocked.getKey(), resultDeleting.getWorkflowStatus()); + + { + // Hazelcast 3.12.4 возможно имеет ошибку с NearCache (https://github.com/hazelcast/hazelcast/issues/16577) и её устранили в версии 3.12.7+. + // метод устранения проблемы: вместо return map.get(paramLong); использовать return map.getEntryView(paramLong).getValue(); + Company resultDeletingDirectGet = companyImdg.getSingleObjectByID(ID); + if (!resultDeleting.getWorkflowStatus().equals(resultDeletingDirectGet.getWorkflowStatus())) { + System.out.println("WARNING: Hazelcast error: WorkflowStatus " + resultDeletingDirectGet.getWorkflowStatus() + " and " + resultDeleting.getWorkflowStatus() + " together!"); + } + } + } + + + /** + * {@link CompanyService#createCompany(BaseRequest)}
+ * Тест проверяет удаление сущности {@link Company} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + void newCompany() throws InterruptedException { + //ARRANGE + final Long ID = 102L; + final String DESTINATION_COMPANY_NEW = Consts.DESTINATION_COMPANY_NEW; + companyImdg.size(); + + CompanyNewRequest companyNewRequest = new CompanyNewRequest(); +// companyNewRequest.setId(ID); + companyNewRequest.setCompanySymbol(CompanySymbol.CLRC.getKey()); + companyNewRequest.setCompanySymbolValue("CLR-symbol ipo"); + companyNewRequest.setShortName("ClrIPO"); + companyNewRequest.setFullName("Clearing IPO"); + companyNewRequest.setWorkflowStatus(WorkflowStatus.Active.getKey()); + + //ACT + String jsonString = getJsonStringForNew(companyNewRequest, ID); + addRecordToKafka((MockConsumer) 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()); + } + + @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/service/CompanySymbolServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java index 456b4a893..1a72f29bf 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,26 +13,45 @@ 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.clearing.platform.dictionary.CompanySymbolDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; +import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.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.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.enumeration.CompanySymbol; 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 ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanySymbolService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + + CompanySymbolValidationConfig.class, + ValidationConfig.class, + BeanConfiguration.class, + + CompanyService.class, + CompanyValidationConfig.class, + AccountNotificationHelper.class, + RelationHelper.class, + + KafkaTestConfig.class, + ImdgTestConfig.class}) class CompanySymbolServiceTest { public static final MatcherFactory.Matcher COMPANY_SYMBOL_MATCHER = usingIgnoringFieldsComparator(); @@ -44,7 +63,7 @@ class CompanySymbolServiceTest { CompanySymbolService companySymbolService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg companySymbolsImdg; @Captor @@ -56,6 +75,26 @@ class CompanySymbolServiceTest { private void init() { 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()); } /** @@ -74,20 +113,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/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..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 @@ -12,32 +12,47 @@ 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.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; -import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.clearing.platform.dictionary.ContactTypeDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.ContactValidationConfig; +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.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 ru.spcex.clearing.company.utils.MatcherFactory.usingIgnoringFieldsComparator; -import static ru.spcex.clearing.company.utils.TestUtils.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, + ContactValidationConfig.class, ContactService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + KafkaTestConfig.class, + ImdgTestConfig.class}) 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 @@ -45,7 +60,7 @@ class ContactServiceTest { @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg contactImdg; @Captor @@ -53,10 +68,53 @@ 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); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); + } + @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); } /** @@ -64,40 +122,38 @@ class ContactServiceTest { * Тест проверяет обновление сущности {@link Contact} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@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 491212001..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; @@ -14,39 +15,58 @@ 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.spcex.clearing.company.config.HazelcastServiceTestConfiguration; -import ru.spcex.clearing.company.config.KafkaConfigTest; -import ru.spcex.clearing.company.utils.MatcherFactory; +import ru.clearing.platform.dictionary.DocumentTypeDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.ProfileDocumentValidationConfig; +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; +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; +import java.time.temporal.ChronoUnit; -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 org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, ProfileDocumentService.class, - KafkaConfigTest.class, - HazelcastServiceTestConfiguration.class}) + AccountNotificationHelper.class, + ProfileDocumentValidationConfig.class, + KafkaTestConfig.class, + ImdgTestConfig.class}) 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 String TOPIC_DESTINATION_PROFILE_DOCUMENT_DELETE = Consts.DESTINATION_PROFILE_DOCUMENT_DELETE; + private static final Long ID = currentID.getAndIncrement(); @Autowired ProfileDocumentService profileDocumentService; @Autowired @Qualifier("hazelcastServiceTest") - private HazelcastService hazelcastServiceTest; + private ImdgProvider hazelcastServiceTest; private Imdg profileDocumentMap; private Imdg companyMap; @@ -55,25 +75,57 @@ class ProfileDocumentServiceTest { @SpyBean private MockProducer mockProducer; + private long COMPANY_ID; + private Company TEST_COMPANY; + + 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(); this.profileDocumentMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); this.companyMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + TEST_COMPANY = new Company(); + TEST_COMPANY.setWorkflowStatus(WorkflowStatus.Active.getKey()); + COMPANY_ID = companyMap.insert(TEST_COMPANY); + + 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); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); } /** - * {@link ProfileDocumentService#newProfileDocument(BaseRequest)}
+ * {@link ProfileDocumentService#profileDocumentNew(BaseRequest)}
* Тест проверяет обновление сущности {@link ProfileDocument} в Hazelcast при передаче из Apache Kafka.
* Входной запрос {@link ProfileDocumentNewRequest}:
*/ @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,10 +134,11 @@ 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(); + predictableProfileDocument.setId(PROFILE_DOCUMENT_ID); predictableProfileDocument.setCompanyId(profileDocumentNewRequest.getCompanyId()); predictableProfileDocument.setDocumentType(profileDocumentNewRequest.getDocumentType()); predictableProfileDocument.setIssueDate(profileDocumentNewRequest.getIssueDate()); @@ -106,8 +159,103 @@ 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); } + + @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); + } + + + @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/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; 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..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 @@ -9,7 +9,9 @@ import ru.spcex.platform.utils.time.TimeUtil; 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 +33,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 +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)); fillBySecurity(object, object.getSecurityId()); return object; } 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(); 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 TemplateMapStoreclasses backend-api imdg + security-util + clearing-validation db-scripts dbf-importer dbf-exporter @@ -32,6 +34,7 @@ scheduler-service clearing-service registry-service + test-clearing 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/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/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/pom.xml b/clearing-parent/securities-service/pom.xml index 6d3e62da1..29185becc 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-validation + ru.spcex.platform platform-imdg-api-hazelcast-impl @@ -41,11 +45,20 @@ jackson-databind + + ru.spcex.clearing + test-clearing + test + org.springframework.boot spring-boot-starter-test test + + ru.spcex.clearing + security-util + @@ -73,6 +86,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 812556ee3..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 @@ -1,24 +1,87 @@ 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; -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.setLotSize(mmsReq.getLotSize()); + listing.setMarket(market); listing.setSymbolCode(mms.getSecuritySymbol()); listing.setSymbolName(mms.getFullName()); listing.setTradingCurrency(mms.getNominalCurrency()); 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()); + listing.setSecurityId(equitySecurity.getId()); + listing.setLotSize(request.getLotSize()); + listing.setMarket(market); + listing.setSymbolCode(equitySecurity.getSecuritySymbol()); + listing.setSymbolName(equitySecurity.getFullName()); +// listing.setTradingCurrency(equitySecurity.getNominalCurrency()); + 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.setMarket(market); + 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(request.getLotSize()); + 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/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..4d1263bc2 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/ValidationConfig.java @@ -0,0 +1,47 @@ +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; + +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") + @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/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..815d779bf --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/config/validation/FixedIncomeCashFlowValidationConfig.java @@ -0,0 +1,97 @@ +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.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; +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_FixedIncomeCashFlow); + return new ValidatorImpl<>(context, + IsLongValueRule.instance("securitySymbol", + FixedIncomeCashFlowNewRequest::getSecuritySymbol, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue), + FieldRequiredRule.instance("securitySymbol", + FixedIncomeCashFlowNewRequest::getSecuritySymbol, + SecuritiesError.RequiredFieldIsEmpty, + securitySymbol -> { + Imdg fixedIncomeCashFlowImdg = context.obtainMap( + IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class + ); + Long securityId = Long.valueOf(securitySymbol); + 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/errors/SecuritiesError.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/errors/SecuritiesError.java index 5b26bbe62..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 @@ -1,12 +1,19 @@ 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 { + UserVerifyDenial(1001L), // 'Нет прав на проведение данной операции + RequiredFieldIsEmpty(1002L), WrongFieldValue(1004L), InstrumentAlreadyExists(1010L), - InstrumentNotActive(1012L), InstrumentNotFound(1011L), + InstrumentNotActive(1012L), + CouponPeriodAlreadyExists(1013L), + CouponPeriodNotFound(1014L), + CurrencyAlreadyExists(1015L), + CurrencyNotFound(1016L), + ; private final Long id; 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..cae5e69ab --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CouponPeriodService.java @@ -0,0 +1,100 @@ +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.util.security.UserRoleVerification; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; + +@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; + 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; + 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.setCouponRate(req.getCouponRate()); + couponPeriod.setNumber(req.getNumber()); + 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 = 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()); + 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/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..9ad133b26 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/CurrencyService.java @@ -0,0 +1,96 @@ +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.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; + +@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 UserRoleVerification userRoleVerification; + private final ValidationHelper validationHelper; + + @Autowired + public CurrencyService(Consumer kafkaQueue, + 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; + } + + @Override + public void afterPropertiesSet() { + callback(CurrencyNewRequest.class) + .setFunction(this::newCurrency) + .forDestination(Consts.DESTINATION_CURRENCY_NEW, callbacks::put); + callback(CurrencyUpdateRequest.class) + .setFunction(this::updateCurrency) + .forDestination(Consts.DESTINATION_CURRENCY_UPDATE, callbacks::put); + imdgProvider.waitAvailable(); + init(); + } + + private RequestInfoUpdate newCurrency(BaseRequest userRequest) { + 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 = 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()); + 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/EquitySecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java new file mode 100644 index 000000000..c19885ee4 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java @@ -0,0 +1,182 @@ +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.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 java.time.Instant; +import java.util.Map; + +@Service +public class EquitySecurityService 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 UserRoleVerification userRoleVerification; + private final ValidationHelper validationHelper; + private final ListingBuilder listingBuilder = new ListingBuilder(); + + @Autowired + public EquitySecurityService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + UserRoleVerification userRoleVerification, + 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.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); + this.validationHelper = validationHelper; + } + + @Override + public void afterPropertiesSet() { + callback(EquitySecurityNewRequest.class) + .setFunction(this::newEquity) + .forDestination(Consts.DESTINATION_EQUITY_SECURITY_NEW, callbacks::put); + callback(EquitySecurityUpdateRequest.class) + .setFunction(this::updateEquity) + .forDestination(Consts.DESTINATION_EQUITY_SECURITY_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::deleteEquity) + .forDestination(Consts.DESTINATION_EQUITY_SECURITY_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(req.workflowStatus); + 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 = 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()); + 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(req.workflowStatus); + 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 = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return 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/FixedIncomeCashFlowService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java new file mode 100644 index 000000000..6b99a0c32 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeCashFlowService.java @@ -0,0 +1,111 @@ +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.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.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; + +import java.util.function.Function; + +@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 UserRoleVerification userRoleVerification; + private final ValidationHelper validationHelper; + + private final Function fixedIncomeCashFlowNewRequestValidator; + private final Function fixedIncomeCashFlowUpdateRequestValidator; + + 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; + 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); + callback(FixedIncomeCashFlowUpdateRequest.class) + .setConsumer(this::fixedIncomeCashFlowUpdate) + .forDestination(Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_UPDATE, callbacks::put); + init(); + } + + public RequestInfoUpdate fixedIncomeCashFlowNew(BaseRequest userRequest) { + log.debug("FixedIncomeCashFlowNewRequest received {}", userRequest.getId()); + + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, fixedIncomeCashFlowNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + 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; + } + + public RequestInfoUpdate fixedIncomeCashFlowUpdate(BaseRequest userRequest) { + log.debug("FixedIncomeCashFlowUpdateRequest received {}", userRequest.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return 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/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..d571ed199 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java @@ -0,0 +1,193 @@ +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.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 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 UserRoleVerification userRoleVerification; + private final ValidationHelper validationHelper; + private final ListingBuilder listingBuilder = new ListingBuilder(); + + @Autowired + public FixedIncomeSecurityService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationProvider validation, + UserRoleVerification userRoleVerification, + ValidationHelper validationHelper) { + super(kafkaQueue, kafkaProducer); + this.validation = validation; + this.fixedIncomeSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class); + this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin); + this.validationHelper = validationHelper; + } + + @Override + public void afterPropertiesSet() { + callback(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("newFixedIncome 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()); + fixedIncome.setNominalValue(req.getNominalValue()); + fixedIncome.setNominalCurrency(req.getNominalCurrency()); + fixedIncome.setMaturityDate(req.getMaturityDate()); + fixedIncome.setCoupon(req.getCoupon()); + fixedIncome.setCouponFrequency(req.getCouponFrequency()); + fixedIncome.setIssuerId(req.getIssuerId()); + fixedIncome.setShortNameEng(req.getShortNameEng()); + fixedIncome.setFullNameEng(req.getFullNameEng()); + fixedIncome.setWorkflowStatus(req.getWorkflowStatus()); + 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("updateFixedIncome received id = {}", req.getId()); + + 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()); + 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()); + fixedIncome.setNominalValue(req.getNominalValue()); + fixedIncome.setNominalCurrency(req.getNominalCurrency()); + fixedIncome.setMaturityDate(req.getMaturityDate()); + fixedIncome.setCoupon(req.getCoupon()); + fixedIncome.setCouponFrequency(req.getCouponFrequency()); + fixedIncome.setIssuerId(req.getIssuerId()); + fixedIncome.setShortNameEng(req.getShortNameEng()); + fixedIncome.setFullNameEng(req.getFullNameEng()); + fixedIncome.setWorkflowStatus(req.getWorkflowStatus()); + 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("updateFixedIncome id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId()); + return null; + } + listing = listingBuilder.byFixedIncomeEquity(fixedIncome, listing); + listingImdg.update(listing); + return null; + } + + private RequestInfoUpdate deleteFixedIncome(BaseRequest userRequest) { + CommonDeleteRequest req = userRequest.getRequestPayload(); + log.debug("CommonDeleteRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.fixedIncomeDeleteValidator()); + 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 ccf129c68..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,6 +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; @@ -30,7 +33,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; @@ -43,6 +45,8 @@ 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(); @@ -51,8 +55,12 @@ 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); this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); @@ -94,30 +102,31 @@ 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()); mms.setStartDate(req.getStartDate()); mms.setEndDate(req.getEndDate()); - mms.setNominalValue(req.getNominalValue() != null ? BigDecimal.valueOf(req.getNominalValue()) : null); + mms.setNominalValue(req.getNominalValue()); + mms.setLotSize(req.getLotSize()); 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.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); @@ -141,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()) { @@ -156,18 +169,29 @@ 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.setNominalValue(req.getNominalValue()); + mms.setLotSize(req.getLotSize()); 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.setIssuerId(req.getIssuerId()); + mms.setSecurityId(mms.getId()); + mms.setDescription(req.getDescription()); + mms.setWorkflowStatus(req.getWorkflowStatus()); + moneyMarketSecurityMap.update(mms); Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); if (listing == null) { log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId()); return null; } - listing.setLotSize(BigDecimal.valueOf(req.getLotSize())); - listing.setUpdated(updateTime); + listing = listingBuilder.byUpdateMms(mms, listing); listingImdg.update(listing); return null; } @@ -175,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()) { @@ -185,9 +214,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) { @@ -195,7 +225,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 481aec643..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 @@ -3,13 +3,11 @@ 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.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.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.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; @@ -23,10 +21,32 @@ import java.util.function.Function; @Component 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; + private final Imdg currencyImdg; + private final Imdg couponPeriodImdg; 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); + this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, SpcexObjectBase.class); + this.couponPeriodImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CouponPeriod, SpcexObjectBase.class); } public Function mmsNewValidator() { @@ -34,9 +54,25 @@ 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), - MmsNewValidationRule.SecuritySymbolUniq + 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, + 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") ); }; } @@ -46,10 +82,25 @@ 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), + EndDtAfterStartDtRule.instance("startDate", "endDate", + MoneyMarketSecurityUpdateRequest::getStartDate, + MoneyMarketSecurityUpdateRequest::getEndDate, + SecuritiesError.RequiredFieldIsEmpty, + SecuritiesError.WrongFieldValue), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), - MmsUpdateValidationRule.StatusIsActive + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), + 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") ); }; } @@ -61,7 +112,182 @@ public class ValidationProvider { context.addImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, mmsMap); return new ValidatorImpl<>(context, new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), - MmsDeleteValidationRule.StatusIsActive + new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), + new WorkflowStatusActv() + ); + }; + } + + public Function equityNewValidator() { + 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, + 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")); + }; + } + + public Function equityUpdateValidator() { + return equityRequest -> { + 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 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")); + }; + } + + public Function equityDeleteValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equityMap); + return new ValidatorImpl<>(context, + 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, 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, + 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") + ); + }; + } + + public Function fixedIncomeUpdateValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + 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 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") + ); + }; + } + + public Function fixedIncomeDeleteValidator() { + return equityRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(equityRequest); + 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"), + new WorkflowStatusActv() + ); + }; + } + + 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 + ); + }; + } + + public Function couponPeriodNewValidator() { + return currencyRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + 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, + FieldRequiredRule.instance("couponRate", + CouponPeriodNewRequest::getCouponRate, + SecuritiesError.RequiredFieldIsEmpty), + FieldRequiredRule.instance("number", + CouponPeriodNewRequest::getNumber, + SecuritiesError.RequiredFieldIsEmpty) + ); + }; + } + + public Function couponPeriodUpdateValidator() { + return currencyRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + 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 new file mode 100644 index 000000000..9546037e3 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodNewValidationRule.java @@ -0,0 +1,37 @@ +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"); + } + 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..bb69fd7a2 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/CouponPeriodUpdateValidationRule.java @@ -0,0 +1,37 @@ +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"); + } + 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/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/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 deleted file mode 100644 index c565f5f83..000000000 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EndDtAfterStartDt.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.spcex.clearing.securities.validation.rule; - -import ru.spcex.clearing.securities.errors.SecuritiesError; -import ru.spcex.platform.classes.base.interfaces.WithEndDt; -import ru.spcex.platform.classes.base.interfaces.WithStartDt; -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 class EndDtAfterStartDt 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().isBefore(validatedObject.getStartDate())) { - return of(SecuritiesError.WrongFieldValue, "endDate"); - } - return empty(); - } -} 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..6e61fb0c8 --- /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/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/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/IsValidInstrumentTypeById.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeById.java new file mode 100644 index 000000000..0c55dc5f0 --- /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.IErrorEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; + +public class IsValidInstrumentTypeById implements IValidationRule> { + private final IErrorEnumId errorEnum; + private final String predictableInstrumentType; + + public IsValidInstrumentTypeById(IErrorEnumId 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/IsValidInstrumentTypeFromRequest.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.java new file mode 100644 index 000000000..76aa065ba --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/IsValidInstrumentTypeFromRequest.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.IErrorEnumId; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.util.Optional; + +public class IsValidInstrumentTypeFromRequest implements IValidationRule> { + private final IErrorEnumId errorEnum; + private final String predictableInstrumentType; + + public IsValidInstrumentTypeFromRequest(IErrorEnumId 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..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 @@ -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 IErrorEnumId errorEnum; + private final Class clazz; + + public NotPresentBySecuritySymbolAndWorkflowStatusActv(String mapName, IErrorEnumId 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/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/HazelcastServiceTestConfiguration.java deleted file mode 100644 index 3af3f0514..000000000 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/config/HazelcastServiceTestConfiguration.java +++ /dev/null @@ -1,73 +0,0 @@ -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.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; - -@Configuration -public class HazelcastServiceTestConfiguration { - 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.newHazelcastInstance(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); - } - - @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; - } -} \ No newline at end of file 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..a7231f52d --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/AbstractServiceTest.java @@ -0,0 +1,133 @@ +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.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; +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; +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; + +import java.util.concurrent.atomic.AtomicLong; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + CouponPeriodService.class, + CurrencyService.class, + 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 Imdg instrumentTypeDictionaryImdg; + protected Imdg workflowStatusDictionaryImdg; + protected Imdg termTypeDictionaryImdg; + protected Imdg currencyCodeDictionaryImdg; + protected Imdg shareTypeDictionaryImdg; + protected Imdg bondTypeDictionaryImdg; + protected Imdg companyImdg; + protected Imdg currencyImdg; + protected Imdg couponPeriodImdg; + + 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; + @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); + 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); + 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); + 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/CouponPeriodServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java new file mode 100644 index 000000000..eada23296 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CouponPeriodServiceTest.java @@ -0,0 +1,121 @@ +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.test.MatcherFactory; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.time.LocalDate; + +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(); + 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)); + 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 + 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 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(testStartDate); + request.setPeriodStartDate(testEndDate); + + //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", predictableCoupon.getSecurityId())); + predictableCoupon.setId(result.getId()); + COUPON_PERIOD_MATCHER.assertMatch(result, predictableCoupon); + } +} 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..03a0cf469 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/CurrencyServiceTest.java @@ -0,0 +1,96 @@ +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.test.MatcherFactory; + +import javax.annotation.PostConstruct; + +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; + + +public class CurrencyServiceTest extends AbstractServiceTest { + private static final MatcherFactory.Matcher CURRENCY_MATCHER = usingIgnoringFieldsComparator(); + 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_CURRENCY_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_CURRENCY_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 new file mode 100644 index 000000000..cb3a86448 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/EquitySecurityServiceTest.java @@ -0,0 +1,199 @@ +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.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.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"); + private final long ID = currentId.getAndIncrement(); + private final int PARTITION = 0; + @Autowired + private EquitySecurityService equitySecurityService; + + @PostConstruct + protected void init() { + super.init(); + } + + /** + * {@link EquitySecurityService#newEquity(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link EquitySecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link EquitySecurityNewRequest}:
+ */ + @Test + public void testNewEquity() { + clearAllInImdg(equitySecurityImdg); + 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 EquitySecurityService#updateEquity(BaseRequest)} + * Тест проверяет обновление сущности {@link EquitySecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link EquitySecurityUpdateRequest}:
+ */ + @Test + public void testUpdateEquity() { + clearAllInImdg(equitySecurityImdg); + 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 EquitySecurityService#deleteEquity(BaseRequest)}
+ * Тест проверяет удаление сущности {@link EquitySecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + public void testDeleteEquity() { + clearAllInImdg(equitySecurityImdg); + 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(issuerId); + 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()); + 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()); + 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/FixedIncomeCashFlowServiceTest.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java new file mode 100644 index 000000000..dad537eb0 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeCashFlowServiceTest.java @@ -0,0 +1,153 @@ +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.platform.messaging.domain.cud.securitites.FixedIncomeCashFlowUpdateRequest; +import ru.spcex.clearing.securities.config.ErrorResolverConfig; +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; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.time.LocalDate; + +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 = { + ErrorResolverConfig.class, + ValidationConfig.class, + FixedIncomeCashFlowService.class, + FixedIncomeCashFlowValidationConfig.class, + KafkaTestConfig.class, + ImdgTestConfig.class}) +class FixedIncomeCashFlowServiceTest { + 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; + 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); + } + + @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/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..aff540631 --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/FixedIncomeSecurityServiceTest.java @@ -0,0 +1,218 @@ +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.FixedIncomeSecurity; +import ru.clearing.classes.statics.data.misc.Listing; +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.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"); + private final long ID = currentId.getAndIncrement(); + private final int PARTITION = 0; + @Autowired + private FixedIncomeSecurityService fixedIncomeSecurityService; + + @PostConstruct + protected void init() { + super.init(); + } + + /** + * {@link FixedIncomeSecurityService#newFixedIncome(BaseRequest)}
+ * Тест проверяет генерацию сущности {@link FixedIncomeSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link FixedIncomeSecurityNewRequest}:
+ */ + @Test + public void newFixedIncome() { + clearAllInImdg(fixedIncomeSecurityImdg); + 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 FixedIncomeSecurityService#updateFixedIncome(BaseRequest)} + * Тест проверяет обновление сущности {@link FixedIncomeSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link FixedIncomeSecurityUpdateRequest}:
+ */ + @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 = 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); + } + + /** + * {@link FixedIncomeSecurityService#deleteFixedIncome(BaseRequest)}
+ * Тест проверяет удаление сущности {@link FixedIncomeSecurity} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + public void deleteFixedIncome() { + 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() { + 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(currencyCode); + fixedIncome.setMaturityDate(LocalDate.now()); + fixedIncome.setCoupon(BigDecimal.valueOf(18.0d)); + fixedIncome.setCouponFrequency(9L); + fixedIncome.setIssuerId(issuerId); + 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 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()); + fixedIncomeSecurityNewRequest.setNominalValue(fixedIncomeSecurity.getNominalValue()); + fixedIncomeSecurityNewRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); + fixedIncomeSecurityNewRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); + fixedIncomeSecurityNewRequest.setCoupon(fixedIncomeSecurity.getCoupon()); + 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 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()); + equitySecurityUpdateRequest.setNominalValue(fixedIncomeSecurity.getNominalValue()); + equitySecurityUpdateRequest.setNominalCurrency(fixedIncomeSecurity.getNominalCurrency()); + equitySecurityUpdateRequest.setMaturityDate(fixedIncomeSecurity.getMaturityDate()); + equitySecurityUpdateRequest.setCoupon(fixedIncomeSecurity.getCoupon()); + 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 86675c716..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 @@ -8,21 +8,30 @@ 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"; - private Double lotSize = 1.0; + private BigDecimal lotSize = BigDecimal.valueOf(341.0); private LocalDate startDate = LocalDate.ofEpochDay(0); - private LocalDate endDate = LocalDate.ofEpochDay(0); - private BigDecimal nominalValue = BigDecimal.valueOf(1.0); - private String instrumentType = "sdgaga"; // (linked to instrumentType) + private LocalDate endDate = LocalDate.now(); + private BigDecimal nominalValue = BigDecimal.valueOf(11.0); + private String instrumentType = RATE; // (linked to instrumentType) private String fullName = "estat"; + private String shortName = "esasdftat"; private String securitySymbol = "sdfafd"; + private String istin = "istin"; + private String termType = AbstractServiceTest.termType; - public MoneyMarketSecurityFactory setLotSize(Double lotSize) { + public String getFullName() { + return fullName; + } + + public MoneyMarketSecurityFactory setLotSize(BigDecimal lotSize) { this.lotSize = lotSize; return this; } @@ -82,14 +91,22 @@ class MoneyMarketSecurityFactory { moneyMarketSecurity.setId(id); moneyMarketSecurity.setSecurityId(securityId); - moneyMarketSecurity.setDescription(description); moneyMarketSecurity.setStartDate(startDate); moneyMarketSecurity.setEndDate(endDate); moneyMarketSecurity.setNominalValue(nominalValue); moneyMarketSecurity.setNominalCurrency(nominalCurrency); 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(lotSize); moneyMarketSecurity.setSecuritySymbol(securitySymbol); + moneyMarketSecurity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey()); return moneyMarketSecurity; } @@ -99,11 +116,22 @@ class MoneyMarketSecurityFactory { = new MoneyMarketSecurityUpdateRequest(); moneyMarketSecurityUpdateRequest.setId(id); + 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); + 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; } @@ -120,11 +148,20 @@ 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); + 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/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..61d5854be --- /dev/null +++ b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/service/MoneyMarketSecurityServiceTest.java @@ -0,0 +1,180 @@ +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.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.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"); + 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"; + BigDecimal updateLotSize = BigDecimal.valueOf(112.0); + + final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory + .getMoneyMarketSecurity(); + moneyMarketSecurityPrediction.setTermType(updateTermType); + moneyMarketSecurityMap.insert(moneyMarketSecurityPrediction); + moneyMarketSecurityPrediction.setTermType(termType); + moneyMarketSecurityPrediction.setLotSize(updateLotSize); + final MoneyMarketSecurityUpdateRequest keyRequest = moneyMarketSecurityFactory + .getMoneyMarketSecurityUpdateRequest(); + keyRequest.setTermType(termType); + keyRequest.setLotSize(updateLotSize); + Listing listingPrediction = new Listing(); + listingPrediction = listingBuilder.byUpdateMms(moneyMarketSecurityPrediction, listingPrediction); + listingImdg.insert(listingPrediction); + listingPrediction.setLotSize(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/MatcherFactory.java b/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/MatcherFactory.java deleted file mode 100644 index 63bd29dab..000000000 --- a/clearing-parent/securities-service/src/test/java/ru/spcex/clearing/securities/utils/MatcherFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.spcex.clearing.securities.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); - } - } -} \ No newline at end of file diff --git a/clearing-parent/security-util/pom.xml b/clearing-parent/security-util/pom.xml new file mode 100644 index 000000000..57332ac31 --- /dev/null +++ b/clearing-parent/security-util/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + security-util + security-util clearing + 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 + provided + + + + + org.springframework + spring-test + test + + + org.skyscreamer + jsonassert + test + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + 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 new file mode 100644 index 000000000..7c1911380 --- /dev/null +++ b/clearing-parent/security-util/src/main/java/ru/spcex/clearing/util/security/UserRoleVerification.java @@ -0,0 +1,148 @@ +package ru.spcex.clearing.util.security; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +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.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; + +/** + * Проверка дополнительных прав пользователя. + *

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

+ * Использовать @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE), требует задание роли через setRoleForVerification(role). + * Либо роль можно задать во втором конструкторе, переопределив её где требуется (если используется scope prototype) + */ +public class UserRoleVerification { + protected Logger log = LoggerFactory.getLogger(getClass()); + + protected Imdg userRoleSessions; + protected UserRole roleForVerification; + protected IErrorEnumId roleVerificationError; + protected IMessageResolver messageResolver; + + public UserRoleVerification(ImdgProvider imdg, + IMessageResolver messageResolver, + IErrorEnumId roleVerificationError) { + Objects.requireNonNull(roleForVerification); + Objects.requireNonNull(roleVerificationError); + Objects.requireNonNull(messageResolver); + userRoleSessions = imdg.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class); + this.messageResolver = messageResolver; + 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()); + } + + 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); + return !roles.isEmpty(); + } + + + 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); + throw new ValidationException(roleVerificationError); + } else { + log.trace("Request without userId"); + } + } + + 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); + String errMsg = messageResolver.resolve(new EnumMessage(roleVerificationError, requesterId)); + return new RequestInfoUpdate() + .setId(req.getId()) + .setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error) + .setMessage(errMsg); + } else { + log.debug("Request without userId"); + } + return null; + } + + public UserRoleVerification setRoleForVerification(UserRole roleForVerification) { + log.debug("{} configure to check role {}", this, 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); +// 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 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; +// } +} diff --git a/clearing-parent/test-clearing/pom.xml b/clearing-parent/test-clearing/pom.xml new file mode 100644 index 000000000..4c1f1dc5e --- /dev/null +++ b/clearing-parent/test-clearing/pom.xml @@ -0,0 +1,64 @@ + + 4.0.0 + + ru.spcex.clearing + clearing-parent + SPCEX-1.0.0.0 + + test-clearing + Test-clearing + SPCEX-1.0.0.0 + + + ru.spcex.platform + platform-imdg-api + + + ru.spcex.platform + platform-messaging + + + org.springframework.boot + spring-boot-starter-web + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework + spring-test + + + org.skyscreamer + jsonassert + + + org.assertj + assertj-core + + + org.reflections + reflections + 0.9.11 + + + org.mockito + mockito-core + + + 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/company-service/src/test/java/ru/spcex/clearing/company/utils/MatcherFactory.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/MatcherFactory.java similarity index 96% rename from clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/MatcherFactory.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/MatcherFactory.java index e850b89ef..6b5f60c45 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/MatcherFactory.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/MatcherFactory.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.company.utils; +package ru.spcex.clearing.test; import java.util.Arrays; diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/TestUtils.java similarity index 75% rename from clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/TestUtils.java index 17cfeb9ca..2d542894e 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/utils/TestUtils.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/TestUtils.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.company.utils; +package ru.spcex.clearing.test; 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.company.utils.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(); @@ -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<>(); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/ImdgTestConfig.java similarity index 67% rename from clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/ImdgTestConfig.java index fbff8eb0c..ca50a9d5f 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/HazelcastServiceTestConfiguration.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/ImdgTestConfig.java @@ -1,12 +1,14 @@ -package ru.spcex.clearing.company.config; +package ru.spcex.clearing.test.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; @@ -16,12 +18,12 @@ import java.util.Random; import java.util.concurrent.atomic.AtomicLong; @Configuration -public class HazelcastServiceTestConfiguration { +public class ImdgTestConfig { public static final AtomicLong currentID = new AtomicLong(0L); 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); @@ -32,8 +34,22 @@ 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"); @@ -44,20 +60,10 @@ 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); } - @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(); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/KafkaConfigTest.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/KafkaTestConfig.java similarity index 81% rename from clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/KafkaConfigTest.java rename to clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/KafkaTestConfig.java index ce31fb986..69665a7f2 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/config/KafkaConfigTest.java +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/config/KafkaTestConfig.java @@ -1,11 +1,9 @@ -package ru.spcex.clearing.company.config; - +package ru.spcex.clearing.test.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; @@ -18,11 +16,12 @@ import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; @Configuration -public class KafkaConfigTest { +public class KafkaTestConfig { @Autowired - @Bean(name = "kafkaSenderTest") - public KafkaSender kafkaSender(Producer kafkaProducer, @Qualifier("hazelcastServiceTest") ImdgProvider imdgProvider) { + @Bean + public KafkaSender kafkaSender(Producer kafkaProducer, + ImdgProvider imdgProvider) { ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator(); return KafkaSender .setup() @@ -36,9 +35,8 @@ public class KafkaConfigTest { } @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - @Bean(name = "mockConsumerTest") - public MockConsumer createConsumer() { + @Bean + public MockConsumer createTestConsumer() { return new MockConsumer<>(OffsetResetStrategy.EARLIEST); } - } diff --git a/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/JsonUtil.java b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/JsonUtil.java new file mode 100644 index 000000000..7a64a96b6 --- /dev/null +++ b/clearing-parent/test-clearing/src/main/java/ru/spcex/clearing/test/json/JsonUtil.java @@ -0,0 +1,73 @@ +package ru.spcex.clearing.test.json; + +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/test/json/MatcherFactoryWithJson.java similarity index 70% 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/test/json/MatcherFactoryWithJson.java index c72317938..1824063ef 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/test/json/MatcherFactoryWithJson.java @@ -1,5 +1,6 @@ -package ru.spcex.clearing.backendapi.controller.utils; +package ru.spcex.clearing.test.json; +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,30 +9,28 @@ 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 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, - (a, e) -> assertThat(a).isEqualTo(e), - (a, e) -> assertThat(a).isEqualTo(e)); + 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, - (a, e) -> assertThat(a).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(e), - (a, e) -> assertThat(a).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(e)); + 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)); } public static class Matcher { 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-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-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..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,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"), CIO("CIO"), UUID("UUID"), + TRDC("TRDC"), CLRC("CLRC"), RGRC("RGRC"); private final String key; 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; + } +} 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-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/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/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..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; @@ -25,11 +26,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 @@ -89,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; + } + /** * возвращает коллекцию объектов, удовлетворяющий условиям на поля */ 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; } 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)); } 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"); } 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..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; @@ -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/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/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index 97ed7998a..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 @@ -5,6 +5,22 @@ 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_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"; + String DESTINATION_COUPON_PERIOD_UPDATE = "coupon_period-update"; + String DESTINATION_KEY_RATE_NEW = "key-rate-new"; String DESTINATION_KEY_RATE_UPDATE = "key-rate-update"; String DESTINATION_KEY_RATE_DELETE = "key-rate-delete"; @@ -21,9 +37,18 @@ 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_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_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"; + 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"; String DESTINATION_CLEARING_MEMBER_CATEGORY_UPDATE = "clearing-member-category-update"; @@ -34,6 +59,8 @@ 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_PROFILE_DOCUMENT_DELETE = "profile-document-delete"; String DESTINATION_SDF08_NEW = "s-df-08-new"; String DESTINATION_SDF02_NEW = "s-df-02-new"; @@ -49,6 +76,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"; 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; + } +} 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/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..66b28a154 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/CompanyNewRequest.java @@ -0,0 +1,68 @@ +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 companySymbol; + @JsonProperty + private String companySymbolValue; + @JsonProperty + private String workflowStatus; + + // for update, это поле может использоваться в gateway-api + @JsonProperty + private Long id; + + 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 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 String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} 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; + } +} 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; + } +} 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; } 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; + } +} 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..6c1d706f1 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodNewRequest.java @@ -0,0 +1,69 @@ +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; + @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; + } + + 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 new file mode 100644 index 000000000..fb0bf2a1b --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/CouponPeriodUpdateRequest.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.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 { + @JsonProperty + public Long id; + @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; + @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; + } + + 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/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; + } +} 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..051273278 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityNewRequest.java @@ -0,0 +1,122 @@ +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; + +import java.math.BigDecimal; + +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 BigDecimal 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 BigDecimal getLotSize() { + return lotSize; + } + + public void setLotSize(BigDecimal 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..10a42dabc --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/EquitySecurityUpdateRequest.java @@ -0,0 +1,134 @@ +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; + +import java.math.BigDecimal; + +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 BigDecimal 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 BigDecimal getLotSize() { + return lotSize; + } + + public void setLotSize(BigDecimal 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/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..dc4ae3c0e --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowNewRequest.java @@ -0,0 +1,75 @@ +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; +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 + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + 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..50d6f0c8c --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeCashFlowUpdateRequest.java @@ -0,0 +1,87 @@ +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; +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 + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + 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; + } + +} 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..6d0112883 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityNewRequest.java @@ -0,0 +1,179 @@ +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.math.BigDecimal; +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 BigDecimal lotSize; + @JsonProperty + public BigDecimal nominalValue; + @JsonProperty + public String nominalCurrency; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate maturityDate; + @JsonProperty + public BigDecimal 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 BigDecimal getLotSize() { + return lotSize; + } + + public void setLotSize(BigDecimal lotSize) { + this.lotSize = lotSize; + } + + public BigDecimal getNominalValue() { + return nominalValue; + } + + public void setNominalValue(BigDecimal 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 BigDecimal getCoupon() { + return coupon; + } + + public void setCoupon(BigDecimal 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..592582ab6 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/securitites/FixedIncomeSecurityUpdateRequest.java @@ -0,0 +1,191 @@ +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.math.BigDecimal; +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 BigDecimal lotSize; + @JsonProperty + public BigDecimal nominalValue; + @JsonProperty + public String nominalCurrency; + @JsonProperty + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate maturityDate; + @JsonProperty + public BigDecimal 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 BigDecimal getLotSize() { + return lotSize; + } + + public void setLotSize(BigDecimal lotSize) { + this.lotSize = lotSize; + } + + public BigDecimal getNominalValue() { + return nominalValue; + } + + public void setNominalValue(BigDecimal 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 BigDecimal getCoupon() { + return coupon; + } + + public void setCoupon(BigDecimal 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; + } +} 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..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 @@ -6,11 +6,14 @@ 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.math.BigDecimal; 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) @@ -20,17 +23,33 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt { @JsonDeserialize(using = LocalDateDeserializer.class) public LocalDate endDate; @JsonProperty - public Double nominalValue; + public BigDecimal nominalValue; @JsonProperty public String nominalCurrency; @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; + public BigDecimal 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; @@ -48,11 +67,11 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt { this.endDate = endDate; } - public Double getNominalValue() { + public BigDecimal getNominalValue() { return nominalValue; } - public void setNominalValue(Double nominalValue) { + public void setNominalValue(BigDecimal nominalValue) { this.nominalValue = nominalValue; } @@ -80,6 +99,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; } @@ -88,11 +115,67 @@ public class MoneyMarketSecurityNewRequest implements WithStartDt, WithEndDt { this.securitySymbol = securitySymbol; } - public Double getLotSize() { + public BigDecimal getLotSize() { return lotSize; } - public void setLotSize(Double lotSize) { + public void setLotSize(BigDecimal 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..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 @@ -6,13 +6,12 @@ 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.math.BigDecimal; 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") @@ -26,15 +25,33 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi @JsonProperty public LocalDate endDate; @JsonProperty - public Double nominalValue; + public BigDecimal nominalValue; @JsonProperty public String nominalCurrency; @JsonProperty public String instrumentType; @JsonProperty + public String shortName; + @JsonProperty public String fullName; @JsonProperty - public Double lotSize; + public String shortNameEng; + @JsonProperty + public String fullNameEng; + @JsonProperty + public String securitySymbol; + @JsonProperty + public BigDecimal 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; @@ -52,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; } @@ -84,11 +101,84 @@ public class MoneyMarketSecurityUpdateRequest implements WithId, WithStartDt, Wi this.fullName = fullName; } - public Double getLotSize() { + 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 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/service/QueueConsumer.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java index ad10ca627..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 @@ -171,6 +171,7 @@ public class QueueConsumer implements AutoCloseable { * @param Класс проверяемого запроса * @return null если ошибок нет */ + @Deprecated public RequestInfoUpdate validate(BaseRequest userRequest, Function validatorBuilder, IMessageResolver messageResolver) { @@ -180,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) 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/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); + } + +} 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(); + } } 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), diff --git a/pom.xml b/pom.xml index 6a001e386..e21bc656f 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,22 @@ ${global.project.version} + + ru.spcex.clearing + clearing-validation + ${global.project.version} + + + ru.spcex.clearing + security-util + ${global.project.version} + + + ru.spcex.clearing + test-clearing + ${global.project.version} + + ru.spcex.platform platform-classes-base