This commit is contained in:
parent
0726c3e321
commit
cef2444524
26 changed files with 613 additions and 8 deletions
|
|
@ -36,6 +36,10 @@
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.spcex.platform</groupId>
|
||||||
|
<artifactId>platform-enum</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package ru.spcex.clearing.balance.config;
|
||||||
|
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.utils.validation.IValidatorContext;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ImdgValidationContext<T> implements IValidatorContext {
|
||||||
|
private final Map<String, Imdg<?>> imdgs;
|
||||||
|
private final Map<Enum<?>, Object> storedObjects;
|
||||||
|
private T validatedObject;
|
||||||
|
|
||||||
|
public ImdgValidationContext() {
|
||||||
|
this.imdgs = new HashMap<>();
|
||||||
|
this.storedObjects = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addImdg(String key, Imdg<?> imdg) {
|
||||||
|
imdgs.put(key, imdg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValidatedObject(T validatedObject) {
|
||||||
|
this.validatedObject = validatedObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getValidatedObject() {
|
||||||
|
return validatedObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeObject(Enum<?> storedObject, Object anyObject) {
|
||||||
|
storedObjects.put(storedObject, anyObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <S> S getStoredObject(Enum<?> storedObject) {
|
||||||
|
Object o = storedObjects.get(storedObject);
|
||||||
|
return (S) o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <V extends SpcexObjectBase> Imdg<V> obtainMap(String mapName, Class<V> clazz) {
|
||||||
|
Imdg<?> imdg = imdgs.get(mapName);
|
||||||
|
if (imdg == null) {
|
||||||
|
throw new IllegalStateException(mapName + " imdg wasn't added to validation context");
|
||||||
|
}
|
||||||
|
return (Imdg<V>) imdg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package ru.spcex.clearing.balance.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||||
|
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||||
|
import ru.spcex.platform.utils.enumeration.SpringPropertiesMessageResolver;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class MessagesConfig {
|
||||||
|
@Bean("validation-error-messages")
|
||||||
|
public ResourceBundleMessageSource messages() {
|
||||||
|
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
|
||||||
|
source.setBasenames("messages/error");
|
||||||
|
source.setUseCodeAsDefaultMessage(true);
|
||||||
|
source.setDefaultEncoding("utf8");
|
||||||
|
source.setDefaultLocale(Locale.ROOT);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public IMessageResolver errorResolver(@Qualifier("validation-error-messages") ResourceBundleMessageSource messageBundle) {
|
||||||
|
SpringPropertiesMessageResolver resolver = new SpringPropertiesMessageResolver(messageBundle);
|
||||||
|
resolver.setLocale("ru");
|
||||||
|
return resolver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package ru.spcex.clearing.balance.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import ru.clearing.classes.statics.data.account.Account;
|
||||||
|
import ru.clearing.classes.statics.data.sdf.SDf01;
|
||||||
|
import ru.spcex.clearing.balance.validation.Sdf01ValidationRule;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
import ru.spcex.platform.utils.validation.IValidator;
|
||||||
|
import ru.spcex.platform.utils.validation.ValidatorImpl;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ValidationConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Bean("sdf01Validator")
|
||||||
|
public Function<SDf01, IValidator> sdf01Validator(ImdgProvider imdgProvider) {
|
||||||
|
return sDf01 -> {
|
||||||
|
ImdgValidationContext<SDf01> context = new ImdgValidationContext<>();
|
||||||
|
context.setValidatedObject(sDf01);
|
||||||
|
BiConsumer<String, Class<? extends SpcexObjectBase>> addImdg = (s, aClass) -> context.addImdg(s, imdgProvider.getImdg(s, aClass));
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
|
return new ValidatorImpl<>(context,
|
||||||
|
Sdf01ValidationRule.AccountPresent,
|
||||||
|
Sdf01ValidationRule.CurrencyCode,
|
||||||
|
Sdf01ValidationRule.CurrentDateOnly,
|
||||||
|
Sdf01ValidationRule.Market,
|
||||||
|
Sdf01ValidationRule.accountType);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package ru.spcex.clearing.balance.errors;
|
||||||
|
|
||||||
|
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||||
|
|
||||||
|
public enum BalanceError implements IEnumId {
|
||||||
|
CompanyNotFound(5211L),
|
||||||
|
CurrencyNotFound(5213L),
|
||||||
|
CurrentDateOnly(5214L),
|
||||||
|
WrongMarket(5215L),
|
||||||
|
WrongAccount(5215L),
|
||||||
|
AccountNotPresent(-1L);
|
||||||
|
;
|
||||||
|
private final Long id;
|
||||||
|
|
||||||
|
BalanceError(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package ru.spcex.clearing.balance.service;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
|
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LoggingService {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
private final IMessageResolver errorResolver;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LoggingService(@Qualifier("errorResolver") IMessageResolver errorResolver) {
|
||||||
|
this.errorResolver = errorResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logError(String message, EnumMessage error, Object... args) {
|
||||||
|
log.error(message + " {}", args, errorResolver.resolve(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logError(EnumMessage error) {
|
||||||
|
log.error("{}", errorResolver.resolve(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
package ru.spcex.clearing.balance.service;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.Consumer;
|
||||||
|
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.account.Account;
|
||||||
|
import ru.clearing.classes.statics.data.company.Company;
|
||||||
|
import ru.clearing.classes.statics.data.sdf.SDf01;
|
||||||
|
import ru.clearing.classes.statics.data.statement.Statement;
|
||||||
|
import ru.spcex.clearing.balance.errors.BalanceError;
|
||||||
|
import ru.spcex.clearing.balance.validation.ValidationStored;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountNewRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
|
import ru.spcex.platform.utils.validation.IValidator;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class StatementService extends QueueConsumer implements InitializingBean {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private final ImdgProvider imdgProvider;
|
||||||
|
private final KafkaSender kafkaReqProducer;
|
||||||
|
private final LoggingService errorLogger;
|
||||||
|
private final Imdg<SDf01> sdf01Imdg;
|
||||||
|
private final Imdg<Company> companyImdg;
|
||||||
|
private final Imdg<Account> accountImdg;
|
||||||
|
private final Imdg<Statement> statementImdg;
|
||||||
|
private final Function<SDf01, IValidator> sDf01Validator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public StatementService(Consumer<String, Object> kafkaQueue, ImdgProvider imdgProvider, KafkaSender kafkaReqProducer, LoggingService errorLogger,
|
||||||
|
@Qualifier("sdf01Validator") Function<SDf01, IValidator> sDf01Validator) {
|
||||||
|
super(kafkaQueue);
|
||||||
|
this.imdgProvider = imdgProvider;
|
||||||
|
this.sdf01Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class);
|
||||||
|
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||||
|
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
|
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
|
||||||
|
this.kafkaReqProducer = kafkaReqProducer;
|
||||||
|
this.errorLogger = errorLogger;
|
||||||
|
this.sDf01Validator = sDf01Validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
callback(StatementRequest.class)
|
||||||
|
.setConsumer(this::process)
|
||||||
|
.forDestination(Consts.DESTINATION_SDF02_NEW, callbacks::put);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(BaseRequest<StatementRequest> systemRequest) {
|
||||||
|
StatementRequest sdfInfo = systemRequest.getRequestPayload();
|
||||||
|
SDf01 sdf01 = sdf01Imdg.getSingleObjectByID(sdfInfo.getSdf01Id());
|
||||||
|
Company company = companyImdg.getSingleObjectByFieldValues(Map.of("tradingCode", sdf01.getDeal()));
|
||||||
|
if (company == null) {
|
||||||
|
errorLogger.logError("sdf01.id={}", new EnumMessage(BalanceError.CompanyNotFound), sdfInfo.getSdf01Id());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IValidator validator = sDf01Validator.apply(sdf01);
|
||||||
|
Optional<EnumMessage> error = validator.tillFirstError();
|
||||||
|
if (BalanceError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
|
||||||
|
kafkaReqProducer.sendRequestToQueue(Consts.ACCOUNT_NEW, createAccountRequest(sdf01.getAccount()));
|
||||||
|
log.info("account not found - send request for creation");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (error.isPresent()) {
|
||||||
|
errorLogger.logError("sdf01.id={}", error.get(), sdf01.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Statement statement = statementImdg.getSingleObjectByFieldValues(Map.of("account", sdf01.getAccount()));
|
||||||
|
|
||||||
|
if (statement == null) {
|
||||||
|
createFlow(sdfInfo, validator.getStored(ValidationStored.Sdf01Account));
|
||||||
|
} else {
|
||||||
|
// updateFlow(statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFlow(StatementRequest sdfInfo, Account storedObject) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private AccountNewRequest createAccountRequest(String account) {
|
||||||
|
AccountNewRequest req = new AccountNewRequest();
|
||||||
|
req.setAccount(account);
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
package ru.spcex.clearing.balance.validation;
|
||||||
|
|
||||||
|
import ru.clearing.classes.statics.data.account.Account;
|
||||||
|
import ru.clearing.classes.statics.data.sdf.SDf01;
|
||||||
|
import ru.spcex.clearing.balance.config.ImdgValidationContext;
|
||||||
|
import ru.spcex.clearing.balance.errors.BalanceError;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.enumeration.AccountType;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
|
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public enum Sdf01ValidationRule implements IValidationRule<ImdgValidationContext<SDf01>> {
|
||||||
|
AccountPresent() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<SDf01> context) {
|
||||||
|
SDf01 sdf01 = context.getValidatedObject();
|
||||||
|
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
|
Account account = accountImdg.getSingleObjectByFieldValues(Map.of("account", sdf01.getAccount(),
|
||||||
|
"accountType", AccountType.Clrn.getKey()));
|
||||||
|
if (account == null) {
|
||||||
|
return of(BalanceError.AccountNotPresent);
|
||||||
|
}
|
||||||
|
context.storeObject(ValidationStored.Sdf01Account, account);
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CurrencyCode() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<SDf01> context) {
|
||||||
|
SDf01 sdf01 = context.getValidatedObject();
|
||||||
|
if (!"RUR".equals(sdf01.getCurr_code())) {
|
||||||
|
return of(BalanceError.CurrencyNotFound);
|
||||||
|
}
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CurrentDateOnly() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<SDf01> context) {
|
||||||
|
SDf01 sdf01 = context.getValidatedObject();
|
||||||
|
//fixme string format???
|
||||||
|
if (!LocalDate.now().toString().equals(sdf01.getDat())) {
|
||||||
|
return of(BalanceError.CurrentDateOnly);
|
||||||
|
}
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Market() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<SDf01> context) {
|
||||||
|
SDf01 sdf01 = context.getValidatedObject();
|
||||||
|
if (!"U".equals(sdf01.getMarket())) {
|
||||||
|
return of(BalanceError.WrongMarket);
|
||||||
|
}
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
accountType() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(ImdgValidationContext<SDf01> context) {
|
||||||
|
SDf01 sdf01 = context.getValidatedObject();
|
||||||
|
if (!"A".equals(sdf01.getAcc_type())) {
|
||||||
|
return of(BalanceError.WrongAccount);
|
||||||
|
}
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@Override
|
||||||
|
public String ruleName() {
|
||||||
|
return "Sdf01ValidationRule." + name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package ru.spcex.clearing.balance.validation;
|
||||||
|
|
||||||
|
public enum ValidationStored {
|
||||||
|
Sdf01Account;
|
||||||
|
}
|
||||||
|
|
@ -3,10 +3,17 @@ balance-service.hazelcast.cluster-members=127.0.0.1
|
||||||
balance-service.hazelcast.login=dev
|
balance-service.hazelcast.login=dev
|
||||||
balance-service.hazelcast.password=dev-pass
|
balance-service.hazelcast.password=dev-pass
|
||||||
|
|
||||||
balance-service.kafka.bootstrap-servers=localhost:9092
|
balance-service.kafka-consumer.bootstrap-servers=localhost:9092
|
||||||
balance-service.kafka.group-id=dev-group
|
balance-service.kafka-consumer.group-id=dev-group
|
||||||
balance-service.kafka.enable-auto-commit=false
|
balance-service.kafka-consumer.enable-auto-commit=false
|
||||||
balance-service.kafka.session-timeout-ms=30000
|
balance-service.kafka-consumer.session-timeout-ms=30000
|
||||||
balance-service.kafka.auto-offset-reset=latest
|
balance-service.kafka-consumer.auto-offset-reset=latest
|
||||||
balance-service.kafka.linger-ms=1
|
balance-service.kafka-consumer.linger-ms=1
|
||||||
balance-service.kafka.buffer-memory=33554432
|
balance-service.kafka-consumer.buffer-memory=33554432
|
||||||
|
|
||||||
|
balance-service.kafka-producer.bootstrap-servers=localhost:9092
|
||||||
|
balance-service.kafka-producer.acks=all
|
||||||
|
balance-service.kafka-producer.retries=0
|
||||||
|
balance-service.kafka-producer.batch-size=16384
|
||||||
|
balance-service.kafka-producer.linger-ms=1
|
||||||
|
balance-service.kafka-producer.buffer-memory=33554432
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
5211=Company not found
|
||||||
|
5213=Currency not found
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
5211=Компания не найдена
|
||||||
|
5213=Валюта не найдена
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package ru.spcex.platform.enumeration;
|
||||||
|
|
||||||
|
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||||
|
|
||||||
|
public enum AccountType implements IEnumKey {
|
||||||
|
Clrn("CLRN");
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
AccountType(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,4 +25,9 @@ public interface Consts {
|
||||||
|
|
||||||
String USER_AUTH_SUCCESS = "user-auth-success";
|
String USER_AUTH_SUCCESS = "user-auth-success";
|
||||||
String USER_LOGOUT_SUCCESS = "user-logout-success";
|
String USER_LOGOUT_SUCCESS = "user-logout-success";
|
||||||
|
|
||||||
|
//todo
|
||||||
|
String STATEMENT_NEW = "statement-action";
|
||||||
|
String ACCOUNT_NEW = "account-new";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package ru.spcex.clearing.platform.messaging.domain.cud.account;
|
||||||
|
|
||||||
|
public class AccountNewRequest {
|
||||||
|
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
public String getAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccount(String account) {
|
||||||
|
this.account = account;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package ru.spcex.clearing.platform.messaging.domain.cud.balance;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
public class StatementRequest {
|
||||||
|
@JsonProperty
|
||||||
|
private Long sdf01Id;
|
||||||
|
|
||||||
|
public Long getSdf01Id() {
|
||||||
|
return sdf01Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSdf01Id(Long sdf01Id) {
|
||||||
|
this.sdf01Id = sdf01Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,6 +35,16 @@
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</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>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -38,4 +38,8 @@ public interface IValidator {
|
||||||
* валидирует все, возвращает первую ошибку - для совместимости
|
* валидирует все, возвращает первую ошибку - для совместимости
|
||||||
*/
|
*/
|
||||||
Optional<EnumMessage> validateAllReturnFirst();
|
Optional<EnumMessage> validateAllReturnFirst();
|
||||||
|
|
||||||
|
default <S> S getStored(Enum<?> storedObject) {
|
||||||
|
throw new UnsupportedOperationException("not implemented");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
package ru.spcex.platform.utils.validation;
|
package ru.spcex.platform.utils.validation;
|
||||||
|
|
||||||
public interface IValidatorContext {}
|
public interface IValidatorContext {
|
||||||
|
default <S> S getStoredObject(Enum<?> storedObject) {
|
||||||
|
throw new UnsupportedOperationException("not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,11 @@ public class ValidatorImpl<C extends IValidatorContext> implements IValidator {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <S> S getStored(Enum<?> storedObject) {
|
||||||
|
return context.getStoredObject(storedObject);
|
||||||
|
}
|
||||||
|
|
||||||
public C getContext() {
|
public C getContext() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package ru.spcex.platform.utils.validation;
|
||||||
|
|
||||||
|
public enum DatePrimitiveValidation {
|
||||||
|
MonthValue
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package ru.spcex.platform.utils.validation;
|
||||||
|
|
||||||
|
public enum DateValidation {
|
||||||
|
LocalDate, Midnight
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.spcex.platform.utils.validation;
|
||||||
|
|
||||||
|
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||||
|
|
||||||
|
public enum TestEnumWithId implements IEnumId {
|
||||||
|
Message1(1L),
|
||||||
|
Message2(2L),
|
||||||
|
Message3(3L),
|
||||||
|
Message4(4L);
|
||||||
|
private final Long id;
|
||||||
|
|
||||||
|
TestEnumWithId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package ru.spcex.platform.utils.validation;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TestValidationContext<T> implements IValidatorContext {
|
||||||
|
private Map<Enum<?>, Object> storedObjects;
|
||||||
|
private T validatedObject;
|
||||||
|
|
||||||
|
public TestValidationContext() {
|
||||||
|
this.storedObjects = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValidatedObject(T validatedObject) {
|
||||||
|
this.validatedObject = validatedObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getValidatedObject() {
|
||||||
|
return validatedObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeObject(Enum<?> storedObject, Object anyObject) {
|
||||||
|
storedObjects.put(storedObject, anyObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <S> S getStoredObject(Enum<?> storedObject) {
|
||||||
|
Object o = storedObjects.get(storedObject);
|
||||||
|
return (S) o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package ru.spcex.platform.utils.validation;
|
||||||
|
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
|
import ru.spcex.platform.utils.time.TimeUtil;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public enum TestValidationRule implements IValidationRule<TestValidationContext<Instant>> {
|
||||||
|
isToday() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(TestValidationContext<Instant> context) {
|
||||||
|
Instant validatedObject = context.getValidatedObject();
|
||||||
|
LocalDate localDate = validatedObject.atZone(TimeUtil.zone).toLocalDate();
|
||||||
|
if (!LocalDate.now().equals(localDate)) {
|
||||||
|
return of(TestEnumWithId.Message1);
|
||||||
|
}
|
||||||
|
context.storeObject(DateValidation.LocalDate, localDate);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isAfterMidnight() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(TestValidationContext<Instant> context) {
|
||||||
|
Instant validatedObject = context.getValidatedObject();
|
||||||
|
Instant midnight = TimeUtil.localDateToInstant(LocalDate.now());
|
||||||
|
if (!validatedObject.isAfter(midnight)) {
|
||||||
|
return of(TestEnumWithId.Message2);
|
||||||
|
}
|
||||||
|
context.storeObject(DateValidation.Midnight, midnight);
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isMonthValid() {
|
||||||
|
@Override
|
||||||
|
public Optional<EnumMessage> validate(TestValidationContext<Instant> context) {
|
||||||
|
Instant validatedObject = context.getValidatedObject();
|
||||||
|
LocalDate localDate = validatedObject.atZone(TimeUtil.zone).toLocalDate();
|
||||||
|
int monthValue = localDate.getMonthValue();
|
||||||
|
if (!(monthValue >= 1 && monthValue <= 12)) {
|
||||||
|
return of(TestEnumWithId.Message3);
|
||||||
|
}
|
||||||
|
context.storeObject(DatePrimitiveValidation.MonthValue, monthValue);
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@Override
|
||||||
|
public String ruleName() {
|
||||||
|
return "TestValidationRule" + name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package ru.spcex.platform.utils.validation;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
|
import ru.spcex.platform.utils.time.TimeUtil;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class ValidatorImplTest {
|
||||||
|
private IValidator validator;
|
||||||
|
@BeforeEach
|
||||||
|
public void initiateValidator() {
|
||||||
|
TestValidationContext<Instant> context = new TestValidationContext<>();
|
||||||
|
context.setValidatedObject(Instant.now());
|
||||||
|
this.validator = new ValidatorImpl<>(context,
|
||||||
|
TestValidationRule.isToday,
|
||||||
|
TestValidationRule.isAfterMidnight,
|
||||||
|
TestValidationRule.isMonthValid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoredObjects() {
|
||||||
|
Optional<EnumMessage> enumMessage = validator.tillFirstError();
|
||||||
|
assertTrue(enumMessage.isEmpty());
|
||||||
|
LocalDate localDate = validator.getStored(DateValidation.LocalDate);
|
||||||
|
assertNotNull(localDate);
|
||||||
|
assertEquals(LocalDate.now(), localDate);
|
||||||
|
Instant midnight = validator.getStored(DateValidation.Midnight);
|
||||||
|
assertNotNull(midnight);
|
||||||
|
assertEquals(LocalDate.now().atStartOfDay().atZone(TimeUtil.zone).toInstant(), midnight);
|
||||||
|
Integer month = validator.getStored(DatePrimitiveValidation.MonthValue);
|
||||||
|
assertNotNull(month);
|
||||||
|
assertEquals(LocalDate.now().getMonthValue(), month);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue