account-service http://jira.mfd.msk:8088/browse/CLS-577, imdg http://jira.mfd.msk:8088/browse/CLS-575 добавил AccountSymbolsUpdate в UpdateMapService.java
This commit is contained in:
parent
9eff119ff2
commit
a2dcd21867
7 changed files with 365 additions and 2 deletions
|
|
@ -0,0 +1,70 @@
|
|||
package ru.spcex.clearing.account.config.validation;
|
||||
|
||||
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.account.AccountSymbols;
|
||||
import ru.spcex.clearing.account.errors.AccountError;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountSymbolsNewRequest;
|
||||
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
import ru.spcex.platform.utils.validation.ValidatorImpl;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Configuration
|
||||
public class AccountSymbolsValidationConfig {
|
||||
|
||||
@Bean("accountSymbolsNewRequest")
|
||||
public Function<AccountSymbolsNewRequest, IValidator> correspondentAccountNewRequestValidator(
|
||||
Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation
|
||||
) {
|
||||
return accountSymbolsNewRequest -> {
|
||||
ImdgValidationContext<AccountSymbolsNewRequest> context = new ImdgValidationContext<>();
|
||||
context.setValidatedObject(accountSymbolsNewRequest);
|
||||
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
||||
addImdg.accept(IMDGDistributedNames.Map_Account);
|
||||
addImdg.accept(IMDGDistributedNames.Map_AccountSymbols);
|
||||
return new ValidatorImpl<>(context,
|
||||
IdPresentRule.instance("accountId",
|
||||
AccountSymbolsNewRequest::getAccountId,
|
||||
IMDGDistributedNames.Map_Account,
|
||||
Account.class,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.CompanyNotFound,
|
||||
false
|
||||
),
|
||||
new DuplicateAccountSymbolsRule()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
static class DuplicateAccountSymbolsRule implements IValidationRule<ImdgValidationContext<AccountSymbolsNewRequest>> {
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<AccountSymbolsNewRequest> context) {
|
||||
AccountSymbolsNewRequest validatedObject = context.getValidatedObject();
|
||||
Imdg<AccountSymbols> accountSymbolsImdg = context.obtainMap(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
|
||||
|
||||
Map<String, Comparable<?>> query = new HashMap<>();
|
||||
query.put("accountId", validatedObject.getAccountId());
|
||||
query.put("accountSymbolValue", validatedObject.getAccountSymbolValue());
|
||||
|
||||
Collection<AccountSymbols> existAccSymbols = accountSymbolsImdg.getCollectionObjectsByFieldValues(query);
|
||||
|
||||
if (existAccSymbols.isEmpty()) {
|
||||
return empty();
|
||||
} else {
|
||||
AccountSymbols existAS = existAccSymbols.iterator().next();
|
||||
return of(AccountError.AccountAlreadyExist, existAS.getAccountId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ public class ValidationConfig {
|
|||
addImdg.accept(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
|
||||
|
||||
//for ClientCodeValidationConfig
|
||||
addImdg.accept(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
package ru.spcex.clearing.account.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.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.account.*;
|
||||
import ru.spcex.clearing.account.errors.AccountError;
|
||||
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.AccountSymbolsNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
|
||||
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.util.services.RequestHelper;
|
||||
import ru.spcex.clearing.validation.common.ValidationHelper;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@Service
|
||||
public class AccountSymbolsService extends QueueConsumer implements InitializingBean {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final ValidationHelper validationHelper;
|
||||
private final UserRoleVerification userRoleVerification;
|
||||
|
||||
private final ImdgProvider imdgProvider;
|
||||
private final Imdg<AccountSymbols> accountSymbolsImdg;
|
||||
|
||||
private final RequestHelper requestHelper;
|
||||
private final Function<AccountSymbolsNewRequest, IValidator> accountSymbolsNewRequestValidator;
|
||||
|
||||
private final IMessageResolver messageResolver;
|
||||
private final Producer<String, Object> kafkaProducer;
|
||||
private final KafkaSender kafkaSender;
|
||||
|
||||
public AccountSymbolsService(Consumer<String, Object> kafkaQueue,
|
||||
Producer<String, Object> kafkaProducer,
|
||||
KafkaSender kafkaSender,
|
||||
ImdgProvider imdgProvider,
|
||||
ValidationHelper validationHelper,
|
||||
UserRoleVerification userRoleVerification,
|
||||
IMessageResolver messageResolver,
|
||||
RequestHelper requestHelper,
|
||||
@Qualifier("accountSymbolsNewRequest")
|
||||
Function<AccountSymbolsNewRequest, IValidator> accountSymbolsNewRequestValidator
|
||||
) {
|
||||
super(kafkaQueue, kafkaProducer);
|
||||
this.kafkaProducer = kafkaProducer;
|
||||
this.kafkaSender = kafkaSender;
|
||||
this.validationHelper = validationHelper;
|
||||
this.userRoleVerification = userRoleVerification;
|
||||
this.requestHelper = requestHelper;
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.accountSymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class);
|
||||
this.accountSymbolsNewRequestValidator = accountSymbolsNewRequestValidator;
|
||||
this.messageResolver = messageResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
imdgProvider.waitAvailable();
|
||||
callback(AccountSymbolsNewRequest.class)
|
||||
.setFunction(this::accountSymbolsNew)
|
||||
.forDestination(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_NEW, callbacks::put);
|
||||
callback(CommonIdRequest.class)
|
||||
.setFunction(this::accountSymbolsDelete)
|
||||
.forDestination(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE, callbacks::put);
|
||||
init();
|
||||
}
|
||||
|
||||
protected RequestInfoUpdate accountSymbolsNew(BaseRequest<AccountSymbolsNewRequest> userRequest) {
|
||||
log.debug("AccountSymbolsNewRequest received, id={}", userRequest.getId());
|
||||
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
|
||||
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||
|
||||
requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, accountSymbolsNewRequestValidator);
|
||||
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||
|
||||
AccountSymbolsNewRequest req = userRequest.getRequestPayload();
|
||||
|
||||
Long id = accountSymbolsImdg.nextIDSequenceFor();
|
||||
AccountSymbols accountSymbols = new AccountSymbols();
|
||||
accountSymbols.setId(id);
|
||||
accountSymbols.setAccountId(req.getAccountId());
|
||||
accountSymbols.setAccountSymbolValue(req.getAccountSymbolValue());
|
||||
|
||||
accountSymbolsImdg.insert(accountSymbols);
|
||||
|
||||
log.debug("successfully processed, id {}. New accountSymbols.id={} was created", id, accountSymbols.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
protected RequestInfoUpdate accountSymbolsDelete(BaseRequest<CommonIdRequest> userRequest) {
|
||||
log.debug("AccountSymbolsDeleteRequest(CommonIdRequest) received, id={}", userRequest.getId());
|
||||
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);
|
||||
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||
|
||||
CommonIdRequest req = userRequest.getRequestPayload();
|
||||
|
||||
AccountSymbols accountSymbols = accountSymbolsImdg.getSingleObjectByID(req.getId());
|
||||
if (accountSymbols == null) {
|
||||
return requestHelper.makeErrorResponse(userRequest, AccountError.AccountNotFound, req.getId());
|
||||
}
|
||||
|
||||
accountSymbolsImdg.delete(accountSymbols);
|
||||
|
||||
log.debug("successfully processed, id {}. New accountSymbols.id={} was deleted", userRequest.getId(), accountSymbols.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
package ru.spcex.clearing.account.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.clearing.classes.statics.data.account.*;
|
||||
import ru.spcex.clearing.account.config.BeanConfiguration;
|
||||
import ru.spcex.clearing.account.config.validation.AccountSymbolsValidationConfig;
|
||||
import ru.spcex.clearing.account.config.validation.ValidationConfig;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountSymbolsNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.test.MatcherFactory;
|
||||
import ru.spcex.clearing.test.TestObjectCreator;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
import ru.spcex.clearing.test.config.KafkaTestConfig;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.TestUtils.*;
|
||||
import static ru.spcex.clearing.test.config.KafkaTestConfig.setMockFuture;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
BeanConfiguration.class,
|
||||
ValidationConfig.class,
|
||||
AccountSymbolsValidationConfig.class,
|
||||
AccountSymbolsService.class,
|
||||
ImdgTestConfig.class,
|
||||
KafkaTestConfig.class})
|
||||
class AccountSymbolsServiceTest {
|
||||
public static final MatcherFactory.Matcher<AccountSymbols> ACCOUNT_SYMBOL_MATCHER = usingIgnoringFieldsComparator();
|
||||
private static final int PARTITION = 0;
|
||||
|
||||
@Autowired
|
||||
AccountSymbolsService accountSymbolsService;
|
||||
@Autowired
|
||||
@Qualifier("hazelcastServiceTest")
|
||||
private ImdgProvider hazelcastServiceTest;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mockProducer")
|
||||
protected Producer<String, Object> mockProducer;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("kafkaTestTemplate")
|
||||
protected KafkaTemplate<String, Object> kafkaTemplate;
|
||||
|
||||
private Imdg<AccountSymbols> accountSymbolsImdg;
|
||||
|
||||
private Imdg<Account> accountImdg;
|
||||
private Long accountId;
|
||||
private Imdg<ClearingAccount> clearingAccountImdg;
|
||||
private Long clearingAccountId;
|
||||
|
||||
static int newRequestCnt = 0;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
hazelcastServiceTest.waitAvailable();
|
||||
accountSymbolsImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_AccountSymbols, AccountSymbols.class
|
||||
);
|
||||
accountImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_Account, Account.class
|
||||
);
|
||||
clearingAccountImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class
|
||||
);
|
||||
|
||||
Account account = new Account();
|
||||
account.setStatus(ServiceStatus.Active.getKey());
|
||||
account.setAccountType(AccountType.Clrn.getKey());
|
||||
accountId = accountImdg.insert(account);
|
||||
|
||||
ClearingAccount clearingAccount = new ClearingAccount();
|
||||
clearingAccount.setAccountId(accountId);
|
||||
clearingAccount.setClearingAccountType("CAT");
|
||||
clearingAccountId = clearingAccountImdg.insert(clearingAccount);
|
||||
|
||||
new TestObjectCreator(hazelcastServiceTest).createUserAdmin(1000L);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
private void destroyTest() {
|
||||
//clean test data
|
||||
Account account = accountImdg.getSingleObjectByID(accountId);
|
||||
if (account != null)
|
||||
accountImdg.delete(account);
|
||||
ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(clearingAccountId);
|
||||
if (clearingAccount != null)
|
||||
clearingAccountImdg.delete(clearingAccount);
|
||||
}
|
||||
|
||||
@Test
|
||||
void tradingClearingRegistryNew_moneyAccount_clearingAccount() {
|
||||
setMockFuture(kafkaTemplate);
|
||||
AccountSymbolsNewRequest accountSymbolsNewRequest = new AccountSymbolsNewRequest();
|
||||
accountSymbolsNewRequest.setAccountId(accountId);
|
||||
accountSymbolsNewRequest.setAccountSymbolValue("SYMBOL1");
|
||||
|
||||
AccountSymbols predictableAccountSymbols = new AccountSymbols();
|
||||
predictableAccountSymbols.setAccountId(accountId);
|
||||
predictableAccountSymbols.setAccountSymbolValue("SYMBOL1");
|
||||
|
||||
String jsonString = getJsonStringForNew(accountSymbolsNewRequest, 0L);
|
||||
|
||||
addRecordToKafka((MockConsumer) accountSymbolsService.getConsumer(),
|
||||
Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_NEW,
|
||||
newRequestCnt,
|
||||
0,
|
||||
jsonString);
|
||||
|
||||
waitingSendAndCheckRecord(0L, mockProducer);
|
||||
|
||||
AccountSymbols resultNew = accountSymbolsImdg.getAllValues().iterator().next();
|
||||
predictableAccountSymbols.setId(resultNew.getId());
|
||||
|
||||
ACCOUNT_SYMBOL_MATCHER.assertMatch(resultNew, predictableAccountSymbols);
|
||||
accountSymbolsImdg.delete(resultNew); // cleanup test
|
||||
|
||||
newRequestCnt++;
|
||||
}
|
||||
|
||||
@Test
|
||||
void tradingClearingRegistryDelete() {
|
||||
AccountSymbols existAccountSymbols = new AccountSymbols();
|
||||
existAccountSymbols.setAccountId(accountId);
|
||||
existAccountSymbols.setAccountSymbolValue("SYMBOL 2");
|
||||
Long accountSymbolId = accountSymbolsImdg.insert(existAccountSymbols);
|
||||
|
||||
CommonDeleteRequest accountSymbolsDeleteRequest = new CommonDeleteRequest();
|
||||
accountSymbolsDeleteRequest.setId(accountSymbolId);
|
||||
|
||||
String jsonString = getJsonStringForDelete(accountSymbolsDeleteRequest, 0);
|
||||
|
||||
//ACT
|
||||
addRecordToKafka((MockConsumer) accountSymbolsService.getConsumer(),
|
||||
Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE,
|
||||
PARTITION,
|
||||
0,
|
||||
jsonString);
|
||||
|
||||
//ASSERT
|
||||
waitingSendAndCheckRecord(0L, mockProducer);
|
||||
|
||||
AccountSymbols resultUpdating = accountSymbolsImdg.getSingleObjectByID(accountSymbolId);
|
||||
Assertions.assertNull(resultUpdating, "Должен был удалиться");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ public class AccountSymbolsController extends AbstractQueueController {
|
|||
@PathVariable("id") Long id) throws ExecutionException, InterruptedException {
|
||||
CommonDeleteAction deleteAction = new CommonDeleteAction();
|
||||
deleteAction.setId(id);
|
||||
return processRequest(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_BLOCK, deleteAction);
|
||||
return processRequest(Consts.DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE, deleteAction);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public class UpdateMapService extends AbstractUpdateMapService {
|
|||
hazelcastServerInstance.getMap(IMDGDistributedNames.Map_Registry).addLocalEntryListener(this, Predicates.alwaysTrue(), true);
|
||||
hazelcastServerInstance.getMap(IMDGDistributedNames.Map_Session).addLocalEntryListener(this, Predicates.alwaysTrue(), true);
|
||||
hazelcastServerInstance.getMap(IMDGDistributedNames.Map_TradingClearingRegistry).addLocalEntryListener(this, Predicates.alwaysTrue(), true);
|
||||
hazelcastServerInstance.getMap(IMDGDistributedNames.Map_AccountSymbols).addLocalEntryListener(this, Predicates.alwaysTrue(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -214,6 +215,11 @@ public class UpdateMapService extends AbstractUpdateMapService {
|
|||
createBusinessEvent(tradingClearingRegistryHistory, eventType);
|
||||
tradingClearingRegistryHistory.setObject((TradingClearingRegistry) value);
|
||||
hazelcastServerInstance.getMap(IMDGDistributedNames.Map_TradingClearingRegistryHistory).put(tradingClearingRegistryHistory.getId(), tradingClearingRegistryHistory);
|
||||
} else if (value instanceof AccountSymbols) {
|
||||
AccountSymbolsHistory accountSymbolsHistory = new AccountSymbolsHistory();
|
||||
createBusinessEvent(accountSymbolsHistory, eventType);
|
||||
accountSymbolsHistory.setObject((AccountSymbols) value);
|
||||
hazelcastServerInstance.getMap(IMDGDistributedNames.Map_TradingClearingRegistryHistory).put(accountSymbolsHistory.getId(), accountSymbolsHistory);
|
||||
|
||||
|
||||
} else if (value instanceof Security) { // Существуют наследники этой таблицы, по этому в последнюю очередь делать эту проверку.
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ public interface Consts {
|
|||
String LAUNCHER_NEW = "launcher-new";
|
||||
|
||||
String DESTINATION_DEPO_ACCOUNT_SYMBOLS_NEW = "depo-accounts-symbols-new";
|
||||
String DESTINATION_DEPO_ACCOUNT_SYMBOLS_BLOCK = "depo-accounts-symbols-block";
|
||||
String DESTINATION_DEPO_ACCOUNT_SYMBOLS_DELETE = "depo-accounts-symbols-delete";
|
||||
|
||||
|
||||
String REQUEST_INFO_UPDATE = "request-info-update";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue