Merge branch 'CLS_258_259' into dev

# Conflicts:
#	clearing-parent/backend-api/src/main/resources/meta/data.xml
#	clearing-parent/backend-api/src/main/resources/meta/meta.xml
This commit is contained in:
AKurakin 2023-04-07 18:50:40 +03:00
commit 700ecaf547
182 changed files with 8806 additions and 1092 deletions

View file

@ -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),

View file

@ -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);
}

View file

@ -67,6 +67,11 @@
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>test-clearing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>

View file

@ -15,7 +15,7 @@ public class AbstractQueueController {
protected <T> CudResponse processRequest(String destination, IAction<T> 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;

View file

@ -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);
}
}

View file

@ -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<CompanyNewRequest> {
@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;
}
}

View file

@ -11,9 +11,6 @@ public class ContactUpdateAction implements IAction<ContactUpdateRequest> {
@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<ContactUpdateRequest> {
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<ContactUpdateRequest> {
this.id = id;
}
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public String getContactType() {
return contactType;
}

View file

@ -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<MoneyMarketSecurity
public LocalDate endDate;
@ApiModelProperty(value = "Номинал", example = "20.5")
@JsonProperty
public Double nominalValue;
public BigDecimal nominalValue;
@ApiModelProperty(value = "Идентификатор валюты номинала", example = "1000")
@JsonProperty
public String nominalCurrency;
@ -47,7 +48,7 @@ public class MoneyMarketSecurityNewAction implements IAction<MoneyMarketSecurity
public String securitySymbol;
@ApiModelProperty(value = "Размер лота", example = "300.5")
@JsonProperty
public Double lotSize;
public BigDecimal lotSize;
@Override
public Collection<EnumMessage> validate() {
@ -107,11 +108,11 @@ public class MoneyMarketSecurityNewAction implements IAction<MoneyMarketSecurity
this.endDate = endDate;
}
public Double getNominalValue() {
public BigDecimal getNominalValue() {
return nominalValue;
}
public void setNominalValue(Double nominalValue) {
public void setNominalValue(BigDecimal nominalValue) {
this.nominalValue = nominalValue;
}
@ -147,11 +148,11 @@ public class MoneyMarketSecurityNewAction implements IAction<MoneyMarketSecurity
this.securitySymbol = securitySymbol;
}
public Double getLotSize() {
public BigDecimal getLotSize() {
return lotSize;
}
public void setLotSize(Double lotSize) {
public void setLotSize(BigDecimal lotSize) {
this.lotSize = lotSize;
}
}

View file

@ -13,6 +13,7 @@ import ru.spcex.platform.classes.base.interfaces.WithId;
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;
@ -35,7 +36,7 @@ public class MoneyMarketSecurityUpdateAction implements IAction<MoneyMarketSecur
public LocalDate endDate;
@ApiModelProperty(value = "Номинал", example = "20.5")
@JsonProperty
public Double nominalValue;
public BigDecimal nominalValue;
@ApiModelProperty(value = "Валюта номинала", example = "RUB")
@JsonProperty
public String nominalCurrency;
@ -47,7 +48,7 @@ public class MoneyMarketSecurityUpdateAction implements IAction<MoneyMarketSecur
public String fullName;
@ApiModelProperty(value = "Размер лота", example = "300.5")
@JsonProperty
public Double lotSize;
public BigDecimal lotSize;
@Override
public MoneyMarketSecurityUpdateRequest toRequest() {
@ -98,11 +99,11 @@ public class MoneyMarketSecurityUpdateAction implements IAction<MoneyMarketSecur
this.endDate = endDate;
}
public Double getNominalValue() {
public BigDecimal getNominalValue() {
return nominalValue;
}
public void setNominalValue(Double nominalValue) {
public void setNominalValue(BigDecimal nominalValue) {
this.nominalValue = nominalValue;
}
@ -130,11 +131,11 @@ public class MoneyMarketSecurityUpdateAction implements IAction<MoneyMarketSecur
this.fullName = fullName;
}
public Double getLotSize() {
public BigDecimal getLotSize() {
return lotSize;
}
public void setLotSize(Double lotSize) {
public void setLotSize(BigDecimal lotSize) {
this.lotSize = lotSize;
}

View file

@ -1,8 +1,8 @@
package ru.spcex.clearing.backendapi.errors;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
public enum BackEndError implements IEnumId {
public enum BackEndError implements IErrorEnumId {
ValidationError(9000L),
UnknownJsonProperty(9001L),
FailedToReadHttpMessage(9002L),

View file

@ -52,6 +52,11 @@ public class ActionField {
@JsonSerialize(using = MetaDataTypeSerializer.class, include = JsonSerialize.Inclusion.NON_EMPTY)
private MetaDataTypes type;
@JsonProperty(value = "webtype")
@JsonDeserialize(using = MetaDataTypeDeserializer.class)
@JsonSerialize(using = MetaDataTypeSerializer.class, include = JsonSerialize.Inclusion.NON_EMPTY)
private MetaDataTypes webtype;
@JsonProperty(value = "virtual")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private Boolean virtual;
@ -115,4 +120,8 @@ public class ActionField {
public void setVirtual(Boolean virtual) {
this.virtual = virtual;
}
public MetaDataTypes getWebtype() {
return webtype;
}
}

View file

@ -5,9 +5,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.spcex.platform.utils.time.TimeUtil;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
@ -82,7 +84,7 @@ public class GetResponseFactory {
currentField = field;
// if (fieldsToAdd.contains(field.getField().getCode())) {
try {
add(r, field.getField().getCode(), field.extractValue(o));
add(r, field, field.extractValue(o));
} catch (Throwable e) {
log.trace(ExceptionUtils.getStackTrace(
new RuntimeException(String.format("Can't extract value for field='%s' of %s(%s): %s -> %s\n%s",
@ -102,9 +104,20 @@ public class GetResponseFactory {
return r;
}
private void add(Map<String, Object> response, String name, Object value) {
private void add(Map<String, Object> 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) {

View file

@ -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()

View file

@ -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;
}

View file

@ -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));
}

View file

@ -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<String, Object> kafka;
private final ImdgId idGenerator;
private final ImdgProvider imdgProvider;
private final ActionValidationProvider validation;
private final Imdg<User> userImdg;
public OperatorImpl(Producer<String, Object> 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<Object> request = new BaseRequest<>();
request.setId(idGenerator.nextId());
request.setActionType(iAction.getActionType());
request.setRequestPayload(iAction.toRequest());
if (appendUserId) {
request.setUserId(currentUserId());
}
//сохраняет данные о запросе в хранилище
saveRequestToStorage(destination, request);
Future<RecordMetadata> send = kafka.send(new ProducerRecord<>(destination, request));

View file

@ -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);
}

View file

@ -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());
}
}

View file

@ -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<BaseRequest> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator(BaseRequest.class);
protected static final MatcherFactory.Matcher<CudResponse> CUD_RESPONSE_MATCHER = usingIgnoringFieldsComparator(CudResponse.class);
protected static final MatcherFactoryWithJson.Matcher<BaseRequest> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparatorForClass(BaseRequest.class);
protected static final MatcherFactoryWithJson.Matcher<CudResponse> CUD_RESPONSE_MATCHER = usingIgnoringFieldsComparatorForClass(CudResponse.class);
protected static final AtomicLong currentId = new AtomicLong();
private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter();

View file

@ -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/";

View file

@ -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/";

View file

@ -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/";

View file

@ -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/";

View file

@ -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)}<br>
* Тест проверяет получение сущности {@link ContactUpdateAction} по REST API и отправку в Apache Kafka.<br>
* Входной запрос {@link ContactUpdateAction}:<br>
* {@link ContactUpdateAction#companyId} - 1000L<br>
* {@link ContactUpdateAction#contactType} - ContactType<br>
* {@link ContactUpdateAction#contactValue} - ContactValue<br>
* {@link ContactUpdateAction#id} - currentId<br>
@ -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());

View file

@ -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/";

View file

@ -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/";

View file

@ -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/";

View file

@ -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/";

View file

@ -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/";

View file

@ -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/";

View file

@ -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/";

View file

@ -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

View file

@ -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/";

View file

@ -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/";

View file

@ -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 <T> List<T> readValues(String json, Class<T> clazz) {
ObjectReader reader = getMapper().readerFor(clazz);
try {
return reader.<T>readValues(json).readAll();
} catch (IOException e) {
throw new IllegalArgumentException("Invalid read array from JSON:\n'" + json + "'", e);
}
}
public static <T> T readValue(String json, Class<T> clazz) {
try {
return getMapper().readValue(json, clazz);
} catch (IOException e) {
throw new IllegalArgumentException("Invalid read from JSON:\n'" + json + "'", e);
}
}
public static <T> String writeValue(T obj) {
try {
return getMapper().writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e);
}
}
public static <T> String writeIgnoreProps(T obj, String... ignoreProps) {
Map<String, Object> map = getMapper().convertValue(obj, new TypeReference<>() {
});
map.keySet().removeAll(Set.of(ignoreProps));
return writeValue(map);
}
}

View file

@ -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<TopicPartition, Long> 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 <T> String getJsonStringForNew(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.NEW);
}
public static <T> String getJsonStringForUPDATE(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.UPDATE);
}
public static <T> String getJsonStringForDELETE(T accountRequest, long id) {
return getJsonBaseRequest(accountRequest, id, ActionType.DELETE);
}
private static <T> String getJsonBaseRequest(T accountRequest, long id, ActionType actionType) {
BaseRequest<T> 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 <T extends SpcexObjectBase> void clearImdg(Imdg<T> imdg) {
Collection<T> values = imdg.getAllValues();
for (T val : values) {
imdg.delete(val);
}
}
public static class FutureRecordMetadata implements Future<RecordMetadata> {
@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;
}
}
}

View file

@ -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),

View file

@ -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);
}

View file

@ -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;
/**
* Инструменты
* <p>
* 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;

View file

@ -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;

View file

@ -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);
}

View file

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>clearing-validation</artifactId> <!-- todo refactor - rename to clearing-validation -->
<name>clearing-validation</name>
<description>Clearing-module, dependency version of platform-utils</description>
<packaging>jar</packaging>
<version>SPCEX-1.0.0.0</version>
<parent>
<artifactId>clearing-parent</artifactId>
<groupId>ru.spcex.clearing</groupId>
<version>SPCEX-1.0.0.0</version>
</parent>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>dictionary</artifactId>
<version>SPCEX-1.0.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-utils</artifactId>
</dependency>
<!-- IMDG -->
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.33</version>
<scope>provided</scope>
</dependency>
<!-- TEST -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-messaging</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,4 @@
/**
* Утилиты с зависимостями от множества модулей clearing-*
*/
package ru.spcex.clearing.util;

View file

@ -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<TIn, TOut extends BaseRequest<?>> 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<TIn> listenClass;
protected long timeout;
/**
* Синхронно-ассинхронный обмен сообщениями
*
* @param kafkaQueue
* @param kafkaProducer
* @param outQueue отправляет в очередь
* @param inQueue слушает очередь, ожидает ответов
* @param listenClass типы объектов из inQueue
* @param timeout - максимальное ожидание ответа, в миллисекундах, 0 - неограничено
*/
public BiDirectionQueueExchanger(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
String outQueue,
String inQueue, Class<TIn> 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);
}
}

View file

@ -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 <R> Класс проверяемого запроса
* @return null если ошибок нет
*/
public <R> RequestInfoUpdate validateTillFirstError(BaseRequest<R> userRequest,
Function<R, IValidator> validatorBuilder) {
if (validatorBuilder != null) {
R req = userRequest.getRequestPayload();
IValidator validator = validatorBuilder.apply(req);
Optional<EnumMessage> 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;
}
}

View file

@ -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 <R> Класс проверяемого объекта
*/
public record DateNotBeforeRule<R>(
String fieldName,
Function<R, LocalDate> getter,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorTaskForPastDate,
boolean required
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемой даты
* @param required Флаг обязательности поля
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorTaskForPastDate Ошибка, которая будет возвращена, если проверяемая дата меньше текущей
* @param <R> Класс проверяемого объекта
*/
public static <R> DateNotBeforeRule<R> instance(String fieldName,
Function<R, LocalDate> getter,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorTaskForPastDate,
boolean required) {
return new DateNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastDate, required);
}
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемой даты
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorTaskForPastDate Ошибка, которая будет возвращена, если проверяемая дата меньше текущей
* @param <R> Класс проверяемого объекта
*/
public static <R> DateNotBeforeRule<R> instance(String fieldName,
Function<R, LocalDate> getter,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorTaskForPastDate) {
return new DateNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastDate, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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();
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <D> Класс словаря
*/
public record DictionaryPresentRule<R, D extends AbstractDictionary>(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorWrongDictionaryValue,
boolean required,
Function<D, IErrorEnumId>[] additionalChecks) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля
* @param getter Метод получения проверяемого значения
* @param dictionaryName Название словаря (см. IMDGDistributedNames)
* @param dictionaryClass Класс словаря (классы *Dictionary.class)
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorWrongDictionaryValue Ошибка, которая будет возвращена, если поле не найдено в словаре
* @param required Флаг обязательности
* @param additionalChecks Дополнительные проверки, связанные с этим полем
* @param <R> Класс проверяемого объекта
* @param <D> Класс словаря
*/
@SafeVarargs
public static <R, D extends AbstractDictionary> DictionaryPresentRule<R, D> instance(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorWrongDictionaryValue,
boolean required,
Function<D, IErrorEnumId>... 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 <R> Класс проверяемого объекта
* @param <D> Класс словаря
*/
@SafeVarargs
public static <R, D extends AbstractDictionary> DictionaryPresentRule<R, D> instance(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorWrongDictionaryValue,
Function<D, IErrorEnumId>... additionalChecks) {
return new DictionaryPresentRule<>(fieldName,
getter,
dictionaryName,
dictionaryClass,
errorEmptyRequiredValue,
errorWrongDictionaryValue,
true,
additionalChecks);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String enumCode = getter.apply(validatedObject);
if (enumCode == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty();
Imdg<D> dictImdg = context.obtainMap(
dictionaryName,
dictionaryClass
);
ImdgPredicateBuilder imdgPredicateBuilder = dictImdg.predicateBuilder();
ImdgPredicate imdgPredicate = imdgPredicateBuilder.equals("code", enumCode);
Collection<D> 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<D, IErrorEnumId> 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 + "}";
}
}

View file

@ -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 <R> Класс проверяемого объекта
*/
public record EndDtAfterStartDtRule<R>(
String endDtFieldName,
String startDtFieldName,
Function<R, LocalDate> getterEndDt,
Function<R, LocalDate> getterStartDt,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorEndDtAfterStartDt,
boolean required
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param endDtFieldName Название поля класса, содержащий EndDt
* @param startDtFieldName Название поля класса, содержащий StartDt
* @param getterEndDt Метод получения проверяемой EndDt
* @param getterStartDt Метод получения проверяемой StartDt
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если одна из дат пустая
* @param errorEndDtAfterStartDt Ошибка, которая будет возвращена, если EndDt > StartDt
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
*/
public static <R> EndDtAfterStartDtRule<R> instance(String endDtFieldName,
String startDtFieldName,
Function<R, LocalDate> getterEndDt,
Function<R, LocalDate> 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 <R> Класс проверяемого объекта
*/
public static <R> EndDtAfterStartDtRule<R> instance(String endDtFieldName,
String startDtFieldName,
Function<R, LocalDate> getterEndDt,
Function<R, LocalDate> getterStartDt,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorEndDtAfterStartDt) {
return new EndDtAfterStartDtRule<>(endDtFieldName,
startDtFieldName,
getterEndDt,
getterStartDt,
errorEmptyRequiredValue,
errorEndDtAfterStartDt,
true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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();
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <E> Enum
*/
public record EnumPresentRule<R, E extends IEnumKey>(String fieldName,
Function<R, String> getter,
E[] enumValues,
boolean required,
IErrorEnumId errorWrongEnumValue,
IErrorEnumId errorEmptyRequiredValue) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля
* @param getter Метод получения проверяемого значения
* @param enumValues Значения из проверяемого множества (Enum.values())
* @param errorWrongEnumValue Ошибка, которая будет возвращена, если поле не найдено в Enum
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param required Флаг обязательности
* @param <R> Класс проверяемого объекта
* @param <E> Enum
*/
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
Function<R, String> 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 <R> Класс проверяемого объекта
* @param <E> Enum
*/
public static <R, E extends IEnumKey> EnumPresentRule<R, E> instance(String fieldName,
Function<R, String> getter,
E[] enumValues,
IErrorEnumId errorWrongEnumValue,
IErrorEnumId errorEmptyRequiredValue) {
return new EnumPresentRule<>(fieldName, getter, enumValues, true, errorWrongEnumValue, errorEmptyRequiredValue);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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 + "}";
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <V> Класс проверяемого значения
*/
public record FieldRequiredRule<R, V>(
String fieldName,
Function<R, V> getter,
IErrorEnumId errorEmptyRequiredValue,
Function<V, IErrorEnumId>[] additionalChecks
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля
* @param getter Метод получения значения
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param additionalChecks Дополнительные проверки, связанные с этим полем
* @param <R> Класс проверяемого объекта
* @param <V> Класс проверяемого значения
*/
@SafeVarargs
public static <R, V> FieldRequiredRule<R, V> instance(String fieldName,
Function<R, V> getter,
IErrorEnumId errorEmptyRequiredValue,
Function<V, IErrorEnumId>... additionalChecks) {
if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue");
return new FieldRequiredRule<>(fieldName, getter, errorEmptyRequiredValue, additionalChecks);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
V value = getter.apply(validatedObject);
if (value == null) return of(errorEmptyRequiredValue, fieldName);
for (Function<V, IErrorEnumId> additionalCheck : additionalChecks) {
IErrorEnumId validationError = additionalCheck.apply(value);
if (validationError != null)
return of(validationError, fieldName);
}
return empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}

View file

@ -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 <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
public record IdPresentRule<R, V extends SpcexObjectBase>(
String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorIdNotPresent,
boolean required,
Function<V, IErrorEnumId>[] additionalChecks
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля, содержащего Id
* @param idGetter Метод получения Id
* @param mapName Название мапы связанного объекта (см. IMDGDistributedNames)
* @param mapClass Класс связанного объекта
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorIdNotPresent Ошибка, которая будет возвращена, если Id не найден
* @param required Флаг обязательности
* @param additionalChecks Дополнительные проверки, которые можно провести со связанным объектом
* @param <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorIdNotPresent,
boolean required,
Function<V, IErrorEnumId> ... 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 <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorIdNotPresent,
Function<V, IErrorEnumId> ... additionalChecks) {
return new IdPresentRule<>(fieldName,
idGetter,
mapName,
mapClass,
errorEmptyRequiredValue,
errorIdNotPresent,
true,
additionalChecks);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
Long id = idGetter.apply(validatedObject);
if (id == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty();
Imdg<V> imdg = context.obtainMap(mapName, mapClass);
V fromMap = imdg.getSingleObjectByID(id);
if (fromMap == null) {
return of(errorIdNotPresent, fieldName);
}
for (Function<V, IErrorEnumId> additionalCheck : additionalChecks) {
IErrorEnumId validationError = additionalCheck.apply(fromMap);
if (validationError != null)
return of(validationError, fieldName);
}
return empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}

View file

@ -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 <R> Класс проверяемого объекта
*/
public record IsLongValueRule<R>(
String fieldName,
Function<R, String> getter,
IErrorEnumId errorEmptyRequiredField,
IErrorEnumId errorWrongFieldValue,
boolean required
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого поля
* @param errorEmptyRequiredField Ошибка, которая будет возвращена, если поле пустое
* @param errorWrongFieldValue Ошибка, которая будет возвращена, если поле нельзя преобразовать в Long
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
*/
public static <R> IsLongValueRule<R> instance(String fieldName,
Function<R, String> 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 <R> Класс проверяемого объекта
*/
public static <R> IsLongValueRule<R> instance(String fieldName,
Function<R, String> getter,
IErrorEnumId errorEmptyRequiredField,
IErrorEnumId errorWrongFieldValue) {
return new IsLongValueRule<>(fieldName, getter, errorEmptyRequiredField, errorWrongFieldValue, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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();
}
}

View file

@ -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 <R> Класс проверяемого объекта
*/
public record TimeNotBeforeRule<R>(
String fieldName,
Function<R, LocalTime> getter,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorTaskForPastTime,
boolean required
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого времени
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorTaskForPastTime Ошибка, которая будет возвращена, если проверяемое время меньше текущего
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
*/
public static <R> TimeNotBeforeRule<R> instance(String fieldName,
Function<R, LocalTime> getter,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorTaskForPastTime,
boolean required) {
return new TimeNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastTime, required);
}
/**
* @param fieldName Название поля класса, используется для передачи ошибки
* @param getter Метод получения проверяемого времени
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorTaskForPastTime Ошибка, которая будет возвращена, если проверяемое время меньше текущего
* @param <R> Класс проверяемого объекта
*/
public static <R> TimeNotBeforeRule<R> instance(String fieldName,
Function<R, LocalTime> getter,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorTaskForPastTime) {
return new TimeNotBeforeRule<>(fieldName, getter, errorEmptyRequiredValue, errorTaskForPastTime, true);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> 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();
}
}

View file

@ -28,6 +28,18 @@
<groupId>ru.spcex.clearing</groupId>
<artifactId>classes</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>security-util</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>clearing-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
@ -41,6 +53,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>test-clearing</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View file

@ -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);
}
}

View file

@ -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<String, Object> createConsumer(CompanyServiceSettings settings) {
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());
}
@Autowired
@Bean
@Bean("kafkaProducer")
public Producer<String, Object> createProducer(CompanyServiceSettings settings) {
return KafkaProducerFactory.producer(settings.getKafkaProducer());
}

View file

@ -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<ClearingMemberCategoryNewRequest, IValidator> clearingMemberCategoryNewRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return clearingMemberCategoryNewRequest -> {
ImdgValidationContext<ClearingMemberCategoryNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingMemberCategoryNewRequest);
Consumer<String> 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<ClearingMemberCategoryUpdateRequest, IValidator> clearingMemberCategoryUpdateRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return clearingMemberCategoryUpdateRequest -> {
ImdgValidationContext<ClearingMemberCategoryUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingMemberCategoryUpdateRequest);
Consumer<String> 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<Company> 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<CommonDeleteRequest, IValidator> clearingMemberCategoryDeleteRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return clearingMemberCategoryDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(clearingMemberCategoryDeleteRequest);
Consumer<String> 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)
);
};
}
}

View file

@ -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<CompanySymbolUpdateRequest, IValidator> companySymbolNewRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companySymbolUpdateRequest -> {
ImdgValidationContext<CompanySymbolUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(companySymbolUpdateRequest);
Consumer<String> 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<CompanySymbolUpdateRequest, IValidator> companySymbolUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companySymbolUpdateRequest -> {
ImdgValidationContext<CompanySymbolUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(companySymbolUpdateRequest);
Consumer<String> 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<ImdgValidationContext<CompanySymbolUpdateRequest>>(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)
);
};
}
}

View file

@ -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<CompanyNewRequest, IValidator> companyNewRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companyNewRequest -> {
ImdgValidationContext<CompanyNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(companyNewRequest);
Consumer<String> 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<CompanyNewRequest, IValidator> companyUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companyNewRequest -> {
ImdgValidationContext<CompanyNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(companyNewRequest);
Consumer<String> 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<CommonDeleteRequest, IValidator> companyDeleteRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companyDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(companyDeleteRequest);
Consumer<String> 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<CompanyInfoUpdateRequest, IValidator> companyInfoUpdateRequestValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return companyDeleteRequest -> {
ImdgValidationContext<CompanyInfoUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(companyDeleteRequest);
Consumer<String> 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)
);
};
}
}

View file

@ -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<ContactNewRequest, IValidator> contactNewRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return contactNewRequest -> {
ImdgValidationContext<ContactNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(contactNewRequest);
Consumer<String> 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<ContactUpdateRequest, IValidator> contactUpdateRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return contactUpdateRequest -> {
ImdgValidationContext<ContactUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(contactUpdateRequest);
Consumer<String> 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)
);
};
}
}

View file

@ -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<ProfileDocumentNewRequest, IValidator> profileDocumentNewRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return profileDocumentNewRequest -> {
ImdgValidationContext<ProfileDocumentNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(profileDocumentNewRequest);
Consumer<String> 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<ProfileDocumentUpdateRequest, IValidator> profileDocumentUpdateRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return profileDocumentUpdateRequest -> {
ImdgValidationContext<ProfileDocumentUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(profileDocumentUpdateRequest);
Consumer<String> 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<CommonDeleteRequest, IValidator> profileDocumentDeleteRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return profileDocumentDeleteRequest -> {
ImdgValidationContext<CommonDeleteRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(profileDocumentDeleteRequest);
Consumer<String> 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)
);
};
}
}

View file

@ -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<String, Imdg<? extends SpcexObjectBase>> imdgForValidation(ImdgProvider imdgProvider) {
final Map<String, Imdg<? extends SpcexObjectBase>> imdg = new HashMap<>();
BiConsumer<String, Class<? extends SpcexObjectBase>> 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);
}
}

View file

@ -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;
}
}

View file

@ -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<LiabilitiesClaimsAssets> liabilitiesClaimsAssetsMap;
Imdg<Account> 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<Account> accounts = accountMap.getCollectionObjectsBySQL("companyId=" + companyId);
log.trace("Found {} accounts by company {}", accounts.size(), companyId);
for (Account account : accounts) {
Collection<LiabilitiesClaimsAssets> 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<Account> accounts = accountMap.getCollectionObjectsBySQL("companyId=" + companyId);
log.trace("Found {} accounts by company {}", accounts.size(), companyId);
// for (Account account : accounts) {
// Collection<LiabilitiesClaimsAssets> 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;
}
}

View file

@ -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<ClearingMemberCategory> clearingMemberCategoryMap;
private final Function<ClearingMemberCategoryNewRequest, IValidator> clearingMemberCategoryNewRequestValidator;
private final Function<ClearingMemberCategoryUpdateRequest, IValidator> clearingMemberCategoryUpdateRequestValidator;
private final Function<CommonDeleteRequest, IValidator> clearingMemberCategoryDeleteRequestValidator;
private final ValidationHelper validationHelper;
private final UserRoleVerification userRoleVerification;
@Autowired
public ClearingMemberCategoryService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
public ClearingMemberCategoryService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
@Qualifier("clearingMemberCategoryNewRequestValidator") Function<ClearingMemberCategoryNewRequest, IValidator> clearingMemberCategoryNewRequestValidator,
@Qualifier("clearingMemberCategoryUpdateRequestValidator") Function<ClearingMemberCategoryUpdateRequest, IValidator> clearingMemberCategoryUpdateRequestValidator,
@Qualifier("clearingMemberCategoryDeleteRequestValidator") Function<CommonDeleteRequest, IValidator> 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<ClearingMemberCategoryNewRequest> userRequest) {
private RequestInfoUpdate clearingMemberCategoryNew(BaseRequest<ClearingMemberCategoryNewRequest> 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<ClearingMemberCategoryUpdateRequest> userRequest) {
public RequestInfoUpdate clearingMemberCategoryUpdate(BaseRequest<ClearingMemberCategoryUpdateRequest> 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<CommonDeleteRequest> userRequest) {
private RequestInfoUpdate clearingMemberCategoryDelete(BaseRequest<CommonDeleteRequest> 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;
}
}

View file

@ -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<CompanyInfo> companyInfoMap;
private final Imdg<Company> companyMap;
protected final CompanyService companyService;
private final RequestHelper requestHelper;
private final ValidationHelper validationHelper;
final Function<CompanyInfoUpdateRequest, IValidator> companyInfoUpdateRequestValidator;
final UserRoleVerification userRoleVerification;
@Autowired
public CompanyInfoService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
ImdgProvider imdgProvider, CompanyService companyService,
RequestHelper requestHelper, ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
@Qualifier("CompanyInfoUpdateRequestValidator")
Function<CompanyInfoUpdateRequest, IValidator> 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<CompanyInfoUpdateRequest> 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<CompanyInfoUpdateRequest> 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;
}
}

View file

@ -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<Company> companyMap;
private final Imdg<CompanyRoleSet> companyRoleSetMap;
private final ImdgId idSequence;
protected UserRoleVerification userRoleVerification;
protected IMessageResolver messageResolver;
private ValidationHelper validationHelper;
// private Function<CompanyRoleSetNewRequest, IValidator> companyNewRequestValidator;
@Autowired
public CompanyRoleSetService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
RequestHelper requestHelper,
ValidationHelper validationHelper,
UserRoleVerification userRoleVerification
// @Qualifier("CompanyRoleSetRequestValidator")
// Function<CompanyRoleSetNewRequest, IValidator> 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<CompanyRoleSetNewRequest> 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<CommonDeleteRequest> 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;
}
}

View file

@ -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<Company> companyMap;
private final RequestHelper requestHelper;
private final ImdgProvider imdgProvider;
private final ImdgId idSequence;
protected UserRoleVerification userRoleVerification;
private ValidationHelper validationHelper;
private Function<CompanyNewRequest, IValidator> companyNewRequestValidator;
private Function<CompanyNewRequest, IValidator> companyUpdateRequestValidator;
private Function<CommonDeleteRequest, IValidator> companyDeleteRequestValidator;
protected CompanySymbolService companySymbolService;
protected AccountNotificationHelper accountNotification;
protected RelationHelper relationHelper;
@Autowired
public CompanyService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
ImdgProvider imdgProvider,
RequestHelper requestHelper,
ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
@Qualifier("companyNewRequestValidator")
Function<CompanyNewRequest, IValidator> companyNewRequestValidator,
@Qualifier("companyUpdateRequestValidator")
Function<CompanyNewRequest, IValidator> companyUpdateRequestValidator,
@Qualifier("CompanyDeleteRequestValidator")
Function<CommonDeleteRequest, IValidator> 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<CommonDeleteRequest> 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<CompanyNewRequest> 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<Company> 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<CompanyNewRequest> 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<Company> 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<Company> 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<CommonDeleteRequest> 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<Company> 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;
}
}

View file

@ -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<CompanySymbols> companySymbolsMap;
private final ImdgProvider imdgProvider;
private final ImdgId idSequence;
protected CompanyService companyService;
private final RequestHelper requestHelper;
protected ValidationHelper validationHelper;
protected UserRoleVerification userRoleVerification;
protected Function<CompanySymbolUpdateRequest, IValidator> companySymbolNewRequestValidator;
protected Function<CompanySymbolUpdateRequest, IValidator> companySymbolUpdateRequestValidator;
@Autowired
public CompanySymbolService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
ImdgProvider imdgProvider,
RequestHelper requestHelper,
ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
@Qualifier("companySymbolNewRequestValidator")
Function<CompanySymbolUpdateRequest, IValidator> companySymbolNewRequestValidator,
@Qualifier("companySymbolUpdateRequestValidator")
Function<CompanySymbolUpdateRequest, IValidator> 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<CompanySymbolUpdateRequest> 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<CompanySymbolUpdateRequest> 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<CompanySymbols> 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<CompanySymbolUpdateRequest> 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<CompanySymbols> 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<CompanySymbols> companySymbolsTMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
companySymbolsTMap.insert(newSymbol);
} else {
Imdg<CompanySymbols> tMap = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
tMap.insert(newSymbol);
}
return newSymbol;
}
}

View file

@ -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<Contact> contactMap;
private final ValidationHelper validationHelper;
private final Function<ContactNewRequest, IValidator> contactNewRequestValidator;
private final Function<ContactUpdateRequest, IValidator> contactUpdateRequestValidator;
private final UserRoleVerification userRoleVerification;
@Autowired
public ContactService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider) {
public ContactService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
ValidationHelper validationHelper,
UserRoleVerification userRoleVerification,
@Qualifier("contactNewRequestValidator") Function<ContactNewRequest, IValidator> contactNewRequestValidator,
@Qualifier("contactUpdateRequestValidator") Function<ContactUpdateRequest, IValidator> 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<ContactUpdateRequest> userRequest) {
ContactUpdateRequest req = userRequest.getRequestPayload();
public RequestInfoUpdate contactNew(BaseRequest<ContactNewRequest> 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<ContactUpdateRequest> 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;
}
}

View file

@ -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<ProfileDocument> profileDocumentMap;
private Imdg<Company> companyMap;
private ImdgProvider imdgProvider;
private KafkaSender kafkaReqProducer;
private AccountNotificationHelper accountNotificationHelper;
private final Function<ProfileDocumentNewRequest, IValidator> profileDocumentNewRequestValidator;
private final Function<ProfileDocumentUpdateRequest, IValidator> profileDocumentUpdateRequestValidator;
private final Function<CommonDeleteRequest, IValidator> profileDocumentDeleteRequestValidator;
private final ValidationHelper validationHelper;
private final UserRoleVerification userRoleVerification;
protected IMessageResolver messageResolver;
protected RequestHelper requestHelper;
@Autowired
public ProfileDocumentService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
KafkaSender kafkaReqProducer,
ImdgProvider imdgProvider) {
ImdgProvider imdgProvider,
UserRoleVerification userRoleVerification,
@Qualifier("profileDocumentNewRequestValidation") Function<ProfileDocumentNewRequest, IValidator> profileDocumentNewRequestValidator,
@Qualifier("profileDocumentUpdateRequestValidation") Function<ProfileDocumentUpdateRequest, IValidator> profileDocumentUpdateRequestValidator,
@Qualifier("profileDocumentDeleteRequestValidation") Function<CommonDeleteRequest, IValidator> 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<ProfileDocumentNewRequest> profileDocumentNewRequestBaseRequest) {
private RequestInfoUpdate profileDocumentNew(BaseRequest<ProfileDocumentNewRequest> 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<CommonDeleteRequest> 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<ProfileDocumentUpdateRequest> 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] согласно описанию с тегом "При расторжении".
*/
}
}

View file

@ -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<Relation> 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<Relation> relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
Collection<Relation> 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);
}
}
}
}

View file

@ -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 <X> request payload type
* @param <T> тип BaseRequest
* @return RequestInfoUpdate или null
*/
public <X, T extends BaseRequest<X>> RequestInfoUpdate requestFunction(RequestCommand<T> 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<T> {
RequestInfoUpdate command(T arg) throws ClearingBaseException;
}
public RequestHelper setLogger(Logger log) {
if (log == null) return this;
this.log = log;
return this;
}
}

View file

@ -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<ImdgValidationContext<CompanyNewRequest>> {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<CompanyNewRequest> 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<CompanySymbols> 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> companySymbols = companySymbolsImdg.getCollectionObjectsByPredicate(andPredicate);
if (companySymbols.isEmpty()) return Optional.empty();
return of(CompanyErrors.CompanyWithCompanySymbolAlreadyExist, companySymbolCode, companySymbolValue);
}
}

View file

@ -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<ImdgValidationContext<CompanySymbolUpdateRequest>> {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<CompanySymbolUpdateRequest> context) {
CompanySymbolUpdateRequest request = context.getValidatedObject();
Imdg<CompanySymbols> companySymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
Collection<CompanySymbols> 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());
}
}

View file

@ -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<ClearingMemberCategory> MEMBER_CATEGORY_MATCHER = usingIgnoringFieldsComparator();
public static final MatcherFactory.Matcher<ClearingMemberCategory> 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<ClearingMemberCategory> memberCategoryImdg;
@Captor
@ -57,22 +70,48 @@ class ClearingMemberCategoryServiceTest {
@SpyBean
private MockProducer<String, Object> 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<ClearingCategoryDictionary> clearingCategoryDictionaryImdg = hazelcastServiceTest.getImdg(
IMDGDistributedNames.Map_ClearingCategoryDictionary,
ClearingCategoryDictionary.class
);
Imdg<Company> 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);

View file

@ -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<CompanyInfo> COMPANY_INFO_MATCHER = usingIgnoringFieldsComparator();
@ -44,7 +64,7 @@ class CompanyInfoServiceTest {
CompanyInfoService companyInfoService;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
private Imdg<Company> 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 <D extends AbstractDictionary /*SpcexObjectBase & Dictionary*/> void putToDictionary(String mapName, D object, String code) {
Imdg<D> 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.<br>
* Входной запрос {@link CompanyInfoUpdateRequest}:<br>
* {@link CompanyInfoUpdateRequest#id} - Идентификатор записи<br>
* {@link CompanyInfoUpdateRequest#corporationSoleType} - 1234<br>
* {@link CompanyInfoUpdateRequest#countryCode} - 1234<br>
* {@link CompanyInfoUpdateRequest#corporationSoleType} - GDIR<br>
* {@link CompanyInfoUpdateRequest#countryCode} - RUS<br>
* {@link CompanyInfoUpdateRequest#description} - updated description<br>
* {@link CompanyInfoUpdateRequest#professionalSign} - 1234<br>
* {@link CompanyInfoUpdateRequest#legalKind} - 1234<br>
* {@link CompanyInfoUpdateRequest#organizationType} - 1234<br>
* {@link CompanyInfoUpdateRequest#residence} - 1234<br>
* {@link CompanyInfoUpdateRequest#professionalSign} - ALWD<br>
* {@link CompanyInfoUpdateRequest#legalKind} - JURD<br>
* {@link CompanyInfoUpdateRequest#organizationType} - NCRD<br>
* {@link CompanyInfoUpdateRequest#residence} - RUS<br>
* {@link CompanyInfoUpdateRequest#shortNameEng} - updated shortNameEng<br>
* {@link CompanyInfoUpdateRequest#fullNameEng} - updated fullNameEng<br>
* {@link CompanyInfoUpdateRequest#shortName} - updated shortName<br>
@ -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");

View file

@ -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<ClearingMemberCategory> 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<Company> companyImdg;
private Imdg<CompanySymbols> companySymbolsImdg;
private Imdg<WorkflowStatusDictionary> workflowStatusDictionaryImdg;
@Captor
private ArgumentCaptor<ProducerRecord> 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<CompanySymbolDictionary> 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)}<br>
* Тест проверяет удаление сущности {@link Company} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link CommonDeleteRequest}:<br>
* {@link CommonDeleteRequest#id} - Идентификатор записи<br>
*/
@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);
}
}

View file

@ -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<CompanySymbols> COMPANY_SYMBOL_MATCHER = usingIgnoringFieldsComparator();
@ -44,7 +63,7 @@ class CompanySymbolServiceTest {
CompanySymbolService companySymbolService;
@Autowired
@Qualifier("hazelcastServiceTest")
private HazelcastService hazelcastServiceTest;
private ImdgProvider hazelcastServiceTest;
private Imdg<CompanySymbols> companySymbolsImdg;
@Captor
@ -56,6 +75,26 @@ class CompanySymbolServiceTest {
private void init() {
hazelcastServiceTest.waitAvailable();
companySymbolsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
Imdg<CompanySymbolDictionary> 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

View file

@ -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> 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<Contact> contactImdg;
@Captor
@ -53,10 +68,53 @@ class ContactServiceTest {
@SpyBean
private MockProducer<String, Object> mockProducer;
private Company TEST_COMPANY;
private Long COMPANY_ID;
@PostConstruct
private void init() {
hazelcastServiceTest.waitAvailable();
contactImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Contact, Contact.class);
Imdg<Company> 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<ContactTypeDictionary> 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.<br>
* Входной запрос {@link ContactUpdateRequest}:<br>
* {@link ContactUpdateRequest#id} - Идентификатор записи<br>
* {@link ContactUpdateRequest#companyId} - Идентификатор записи<br>
* {@link ContactUpdateRequest#contactType} - 1234<br>
* {@link ContactUpdateRequest#contactType} - ADDR<br>
* {@link ContactUpdateRequest#contactValue} - new ContactValue<br>
*/
@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);
}
}

View file

@ -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<ProfileDocument> 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<ProfileDocument> profileDocumentMap;
private Imdg<Company> companyMap;
@ -55,25 +75,57 @@ class ProfileDocumentServiceTest {
@SpyBean
private MockProducer<String, Object> 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<DocumentTypeDictionary> 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)} <br>
* {@link ProfileDocumentService#profileDocumentNew(BaseRequest)} <br>
* Тест проверяет обновление сущности {@link ProfileDocument} в Hazelcast при передаче из Apache Kafka.<br>
* Входной запрос {@link ProfileDocumentNewRequest}:<br>
*/
@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);
}
}

View file

@ -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;

View file

@ -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<EquitySecurity> {
@ -31,7 +33,7 @@ public class EquitySecurityMapStore extends TemplateMapStore<EquitySecurity> {
@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<EquitySecurity> {
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;
}

View file

@ -30,10 +30,14 @@ public class UserMapStore extends TemplateMapStore<User> {
@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();

View file

@ -72,7 +72,7 @@ public class MoneyMarketSecurityMapStore extends TemplateMapStore<MoneyMarketSec
object.setNominalValue(resultSet.getObject("NOMINAL_VALUE", BigDecimal.class));
object.setNominalCurrency(resultSet.getObject("NOMINAL_CURRENCY", String.class));
object.setTermType(resultSet.getObject("TERM_TYPE", String.class));
object.setTermType(resultSet.getObject("LOT_SIZE", String.class));
object.setLotSize(resultSet.getObject("LOT_SIZE", BigDecimal.class));
fillBySecurity(object, object.getSecurityId());
return object;
}

View file

@ -115,7 +115,7 @@ public abstract class AbstractHazelcastLifecycleSupport implements InitializingB
throw new RuntimeException("MapStore multithreaded not complete.", e);
}
HazelcastHelper.otcSystem_setStorageState(true, hazelcastServerInstance);
HazelcastHelper.imdgSystem_setStorageState(true, hazelcastServerInstance);
loadTime = System.currentTimeMillis() - loadTime;
log.info("All map load time {} ms", loadTime);

View file

@ -20,6 +20,8 @@
<module>classes</module>
<module>backend-api</module>
<module>imdg</module>
<module>security-util</module>
<module>clearing-validation</module>
<module>db-scripts</module>
<module>dbf-importer</module>
<module>dbf-exporter</module>
@ -32,6 +34,7 @@
<module>scheduler-service</module>
<module>clearing-service</module>
<module>registry-service</module>
<module>test-clearing</module>
</modules>
<properties>

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -24,6 +24,10 @@
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-enum</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>clearing-validation</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.platform</groupId>
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
@ -41,11 +45,20 @@
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>test-clearing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ru.spcex.clearing</groupId>
<artifactId>security-util</artifactId>
</dependency>
</dependencies>
<build>
@ -73,6 +86,23 @@
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0-M1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0-M1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

View file

@ -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;
}
}

View file

@ -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<String, Object> createConsumer(SecuritiesServiceSettings settings) {
return KafkaConsumerFactory.consumer(settings.getKafkaConsumer());

View file

@ -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<String, Imdg<? extends SpcexObjectBase>> imdgForValidation(ImdgProvider imdgProvider) {
final Map<String, Imdg<? extends SpcexObjectBase>> imdg = new HashMap<>();
BiConsumer<String, Class<? extends SpcexObjectBase>> 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);
}
}

View file

@ -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<FixedIncomeCashFlowNewRequest, IValidator> fixedIncomeCashFlowNewRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return fixedIncomeCashFlowNewRequest -> {
ImdgValidationContext<FixedIncomeCashFlowNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(fixedIncomeCashFlowNewRequest);
Consumer<String> 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<FixedIncomeCashFlow> fixedIncomeCashFlowImdg = context.obtainMap(
IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class
);
Long securityId = Long.valueOf(securitySymbol);
Collection<FixedIncomeCashFlow> 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<FixedIncomeCashFlowUpdateRequest, IValidator> fixedIncomeCashFlowUpdateRequestValidator(
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
) {
return fixedIncomeCashFlowUpdateRequest -> {
ImdgValidationContext<FixedIncomeCashFlowUpdateRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(fixedIncomeCashFlowUpdateRequest);
Consumer<String> 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;
})
);
};
}
}

View file

@ -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;

View file

@ -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<CouponPeriod> 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<String, Object> kafkaQueue,
Producer<String, Object> 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<CouponPeriodNewRequest> 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<CouponPeriodUpdateRequest> 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;
}
}

View file

@ -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<Currency> 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<String, Object> kafkaQueue,
Producer<String, Object> 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<CurrencyNewRequest> 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<CurrencyUpdateRequest> 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;
}
}

View file

@ -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<EquitySecurity> equitySecurityImdg;
private final Imdg<Listing> 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<String, Object> kafkaQueue,
Producer<String, Object> 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<EquitySecurityNewRequest> 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<EquitySecurity> equityImdg = transaction.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class);
Imdg<Listing> 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<EquitySecurityUpdateRequest> 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<CommonDeleteRequest> 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;
}
}

View file

@ -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<FixedIncomeCashFlow> fixedIncomeCashFlowImdg;
private final ImdgProvider imdgProvider;
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
private final Function<FixedIncomeCashFlowNewRequest, IValidator> fixedIncomeCashFlowNewRequestValidator;
private final Function<FixedIncomeCashFlowUpdateRequest, IValidator> fixedIncomeCashFlowUpdateRequestValidator;
public FixedIncomeCashFlowService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaResponseQueue,
ImdgProvider imdgProvider,
UserRoleVerification userRoleVerification,
ValidationHelper validationHelper,
@Qualifier("fixedIncomeCashFlowNewRequestValidator") Function<FixedIncomeCashFlowNewRequest, IValidator> fixedIncomeCashFlowNewRequestValidator,
@Qualifier("fixedIncomeCashFlowUpdateRequestValidator") Function<FixedIncomeCashFlowUpdateRequest, IValidator> 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<FixedIncomeCashFlowNewRequest> 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<FixedIncomeCashFlowUpdateRequest> 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;
}
}

Some files were not shown because too many files have changed in this diff Show more