Creating ClearingServiceTest for clearing-service. Fixing bug in ValidationConfig.
This commit is contained in:
parent
18959e3beb
commit
a8a4d99113
8 changed files with 598 additions and 7 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
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">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>clearing-parent</artifactId>
|
<artifactId>clearing-parent</artifactId>
|
||||||
|
|
@ -55,6 +55,11 @@
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package ru.spcex.clearing.config;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import ru.clearing.classes.statics.data.account.Account;
|
||||||
|
import ru.clearing.classes.statics.data.account.AccountBalance;
|
||||||
import ru.clearing.classes.statics.data.company.Company;
|
import ru.clearing.classes.statics.data.company.Company;
|
||||||
import ru.clearing.classes.statics.data.company.relation.Relation;
|
import ru.clearing.classes.statics.data.company.relation.Relation;
|
||||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||||
|
|
@ -24,14 +26,16 @@ import java.util.function.BiFunction;
|
||||||
@Configuration
|
@Configuration
|
||||||
public class ValidationConfig {
|
public class ValidationConfig {
|
||||||
private final Map<String, Imdg<? extends SpcexObjectBase>> imdgs;
|
private final Map<String, Imdg<? extends SpcexObjectBase>> imdgs;
|
||||||
|
private final BiConsumer<ImdgValidationContext<?>, String> addImdg = (context, s)
|
||||||
|
-> context.addImdg(s, getImdg(s));
|
||||||
|
|
||||||
public ValidationConfig(ImdgProvider imdgProvider) {
|
public ValidationConfig(ImdgProvider imdgProvider) {
|
||||||
this.imdgs = new HashMap<>();
|
this.imdgs = new HashMap<>();
|
||||||
BiConsumer<String, Class<? extends SpcexObjectBase>> addImdg = (s, aClass) -> imdgs.put(s, imdgProvider.getImdg(s, aClass));
|
BiConsumer<String, Class<? extends SpcexObjectBase>> addImdg = (s, aClass) -> imdgs.put(s, imdgProvider.getImdg(s, aClass));
|
||||||
addImdg.accept(IMDGDistributedNames.Map_Relation, Relation.class);
|
addImdg.accept(IMDGDistributedNames.Map_Relation, Relation.class);
|
||||||
addImdg.accept(IMDGDistributedNames.Map_Company, Company.class);
|
addImdg.accept(IMDGDistributedNames.Map_Company, Company.class);
|
||||||
addImdg.accept(IMDGDistributedNames.Map_Account, Company.class);
|
addImdg.accept(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
addImdg.accept(IMDGDistributedNames.Map_AccountBalance, Company.class);
|
addImdg.accept(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,9 +45,6 @@ public class ValidationConfig {
|
||||||
return imdgs.get(key);
|
return imdgs.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BiConsumer<ImdgValidationContext<?>, String> addImdg = (context, s)
|
|
||||||
-> context.addImdg(s, getImdg(s));
|
|
||||||
|
|
||||||
@Bean("executionDepositValidator")
|
@Bean("executionDepositValidator")
|
||||||
public BiFunction<ClearingCategory, ExecutionDeposit, IValidator> executionDepositValidator() {
|
public BiFunction<ClearingCategory, ExecutionDeposit, IValidator> executionDepositValidator() {
|
||||||
return (category, execDeposit) -> {
|
return (category, execDeposit) -> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
package ru.spcex.clearing.config;
|
||||||
|
|
||||||
|
import com.hazelcast.config.*;
|
||||||
|
import com.hazelcast.core.Hazelcast;
|
||||||
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class HazelcastServiceTestConfiguration {
|
||||||
|
|
||||||
|
public static final AtomicLong currentID = new AtomicLong(0L);
|
||||||
|
private HazelcastInstance hazelcastInstance;
|
||||||
|
|
||||||
|
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
|
||||||
|
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
|
||||||
|
if (maxPoolSz > 2) {
|
||||||
|
pool.setKeepAliveSeconds(60);
|
||||||
|
pool.setAllowCoreThreadTimeOut(true);
|
||||||
|
}
|
||||||
|
pool.setCorePoolSize(maxPoolSz);
|
||||||
|
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "hazelcastServiceTest")
|
||||||
|
public HazelcastService hazelcastService(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, HazelcastClientParams params) {
|
||||||
|
Config cfg = new Config();
|
||||||
|
cfg.setInstanceName("localhost");
|
||||||
|
|
||||||
|
NetworkConfig networkConfig = new NetworkConfig();
|
||||||
|
JoinConfig joinConfig = new JoinConfig();
|
||||||
|
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
|
||||||
|
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(true).setMembers(List.of("127.0.0.1")));
|
||||||
|
networkConfig.setJoin(joinConfig);
|
||||||
|
cfg.setNetworkConfig(networkConfig);
|
||||||
|
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance(cfg);
|
||||||
|
HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance);
|
||||||
|
return new HazelcastService(taskExecutorHazelcastClientInitializer, taskExecutorIdGeneratorAwaiter, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "taskExecutorHazelcastClientInitializer")
|
||||||
|
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
|
||||||
|
return createThreadPoolTaskExecutor(1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "taskExecutorIdGeneratorAwaiter")
|
||||||
|
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
|
||||||
|
return createThreadPoolTaskExecutor(1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "hazelcastClientParams")
|
||||||
|
public HazelcastClientParams getHazelcastClientParams() {
|
||||||
|
HazelcastClientParams params = new HazelcastClientParams();
|
||||||
|
params.setLogin("dev");
|
||||||
|
params.setPassword("dev-pass");
|
||||||
|
params.setClusterMembers("127.0.0.1");
|
||||||
|
params.setInstanceName("hzTestClient" + new Random().nextInt());
|
||||||
|
params.setNearCacheConfig(new NearCacheConfig());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package ru.spcex.clearing.config;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||||
|
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
|
||||||
|
import org.apache.kafka.clients.producer.Producer;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgId;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class KafkaConfigTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Bean(name = "kafkaSenderTest")
|
||||||
|
public KafkaSender kafkaSender(Producer<String, Object> kafkaProducer, @Qualifier("hazelcastServiceTest") ImdgProvider imdgProvider) {
|
||||||
|
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
|
||||||
|
return KafkaSender
|
||||||
|
.setup()
|
||||||
|
.producer(kafkaProducer)
|
||||||
|
.idGenerator(imdgIdGenerator::nextId)
|
||||||
|
.imdgProvider(s -> {
|
||||||
|
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
|
||||||
|
return imdg::insert;
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
@Bean(name = "mockConsumerTest")
|
||||||
|
public MockConsumer<String, Object> createConsumer() {
|
||||||
|
return new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package ru.spcex.clearing.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import ru.spcex.clearing.utils.TestUtils;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||||
|
|
||||||
|
public class PaymentInstructionCreatorConfigTest {
|
||||||
|
|
||||||
|
@Bean(name = "paymentInstructionCreatorTest")
|
||||||
|
public TestUtils.PaymentInstructionCreatorTest createPaymentInstructionCreator(@Qualifier("hazelcastServiceTest") HazelcastService hazelcastServiceTest) {
|
||||||
|
return new TestUtils.PaymentInstructionCreatorTest(hazelcastServiceTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,275 @@
|
||||||
|
package ru.spcex.clearing.service;
|
||||||
|
|
||||||
|
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||||
|
import org.apache.kafka.clients.producer.MockProducer;
|
||||||
|
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
import ru.clearing.classes.statics.data.account.Account;
|
||||||
|
import ru.clearing.classes.statics.data.account.AccountBalance;
|
||||||
|
import ru.clearing.classes.statics.data.company.Company;
|
||||||
|
import ru.clearing.classes.statics.data.company.relation.Relation;
|
||||||
|
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||||
|
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
|
||||||
|
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
||||||
|
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney;
|
||||||
|
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||||
|
import ru.spcex.clearing.config.*;
|
||||||
|
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.CommonIdRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.registry.DealRegisterNewRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||||
|
import ru.spcex.clearing.service.builder.LiabilitiesClaimsAssetsCreator;
|
||||||
|
import ru.spcex.clearing.service.builder.LiabilitiesClaimsMoneyCreator;
|
||||||
|
import ru.spcex.clearing.service.order.ExecutionDepositSorter;
|
||||||
|
import ru.spcex.clearing.service.order.PaymentInstructionSorter;
|
||||||
|
import ru.spcex.clearing.utils.MatcherFactory;
|
||||||
|
import ru.spcex.clearing.utils.TestUtils;
|
||||||
|
import ru.spcex.platform.enumeration.*;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||||
|
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import static ru.spcex.clearing.config.HazelcastServiceTestConfiguration.currentID;
|
||||||
|
import static ru.spcex.clearing.utils.MatcherFactory.usingIgnoringFieldsComparator;
|
||||||
|
import static ru.spcex.clearing.utils.TestUtils.addRecordToKafka;
|
||||||
|
import static ru.spcex.clearing.utils.TestUtils.getJsonStringForNew;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@ContextConfiguration(classes = {
|
||||||
|
SdfCreatorBySTLDPayment.class,
|
||||||
|
PaymentUpdateBySdf04.class,
|
||||||
|
VerificationResultComponent.class,
|
||||||
|
ExecutionDepositComponent.class,
|
||||||
|
ExecutionDepositSorter.class,
|
||||||
|
LiabilitiesClaimsAssetsCreator.class,
|
||||||
|
LiabilitiesClaimsMoneyCreator.class,
|
||||||
|
EventsReceiver.class,
|
||||||
|
ClearingService.class,
|
||||||
|
Clearing.class,
|
||||||
|
SortingConfig.class,
|
||||||
|
PaymentInstructionSorter.class,
|
||||||
|
MessageResolverConfig.class,
|
||||||
|
PaymentInstructionCreatorConfigTest.class,
|
||||||
|
ValidationConfig.class,
|
||||||
|
KafkaConfigTest.class,
|
||||||
|
HazelcastServiceTestConfiguration.class})
|
||||||
|
class ClearingServiceTest {
|
||||||
|
public static final MatcherFactory.Matcher<LiabilitiesClaimsAssets> LIABILITIES_CLAIMS_ASSETS_MATCHER = usingIgnoringFieldsComparator("created", "updated");
|
||||||
|
public static final MatcherFactory.Matcher<LiabilitiesClaimsMoney> LIABILITIES_CLAIMS_MONEY_MATCHER = usingIgnoringFieldsComparator("created", "updated");
|
||||||
|
public static final MatcherFactory.Matcher<PaymentInstruction> PAYMENT_INSTRUCTION_MATCHER = usingIgnoringFieldsComparator("created", "updated");
|
||||||
|
public static final MatcherFactory.Matcher<ExecutionDeposit> EXECUTION_DEPOSIT_MATCHER = usingIgnoringFieldsComparator("created", "updated");
|
||||||
|
private static final int PARTITION = 0;
|
||||||
|
private static final String TOPIC_START_CLEARING = Task.startOfClearing.topic();
|
||||||
|
private static final String TOPIC_CONTINUE_CLEARING = Consts.CONTINUE_CLEARING;
|
||||||
|
private static final Long ID = currentID.getAndIncrement();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
EventsReceiver eventsReceiver;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
LiabilitiesClaimsAssetsCreator lbltsClmsAssetsCreator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("paymentInstructionCreatorTest")
|
||||||
|
TestUtils.PaymentInstructionCreatorTest paymentInstructionCreator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
LiabilitiesClaimsMoneyCreator lbltsClmsMoneyCreator;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("hazelcastServiceTest")
|
||||||
|
private HazelcastService hazelcastServiceTest;
|
||||||
|
private Imdg<ExecutionDeposit> executionDepositImdg;
|
||||||
|
private Imdg<LiabilitiesClaimsAssets> liabilitiesClaimsAssetsImdg;
|
||||||
|
private Imdg<LiabilitiesClaimsMoney> liabilitiesClaimsMoneyImdg;
|
||||||
|
private Imdg<ClearingMemberCategory> clearingCategoryImdg;
|
||||||
|
private Imdg<Relation> relationImdg;
|
||||||
|
private Imdg<Company> companyImdg;
|
||||||
|
private Imdg<Account> accountImdg;
|
||||||
|
private Imdg<AccountBalance> accountBalanceImdg;
|
||||||
|
private ClearingCategory category;
|
||||||
|
private ExecutionDeposit executionDeposit;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<ProducerRecord> producerRecord;
|
||||||
|
@SpyBean
|
||||||
|
private MockProducer<String, Object> mockProducer;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
private void init() {
|
||||||
|
hazelcastServiceTest.waitAvailable();
|
||||||
|
this.executionDepositImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
|
||||||
|
this.clearingCategoryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||||
|
this.liabilitiesClaimsAssetsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsAssets, LiabilitiesClaimsAssets.class);
|
||||||
|
this.liabilitiesClaimsMoneyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsMoney, LiabilitiesClaimsMoney.class);
|
||||||
|
|
||||||
|
this.relationImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
|
||||||
|
this.companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||||
|
this.accountImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
|
this.accountBalanceImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);
|
||||||
|
TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class);
|
||||||
|
doReturn(future).when(mockProducer).send(producerRecord.capture());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ClearingService#executeClearing()} <br>
|
||||||
|
* Тест проверяет создание сущности {@link LauncherCommandRequest} в Hazelcast при передаче из Apache Kafka.<br>
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void startClearingNew() {
|
||||||
|
//ARRANGE
|
||||||
|
Long companyIdI1 = 11L;
|
||||||
|
Long relationIdI1 = 111L;
|
||||||
|
Long accountIdI1 = 1111L;
|
||||||
|
Long securityIdI1 = 11111L;
|
||||||
|
LocalDate firstSettlementDateI1 = LocalDate.now();
|
||||||
|
LocalDate secondSettlementDateI2 = LocalDate.ofYearDay(2022, 31);
|
||||||
|
|
||||||
|
preparOptimisticCase(companyIdI1, relationIdI1, accountIdI1,
|
||||||
|
securityIdI1, firstSettlementDateI1, secondSettlementDateI2, "I");
|
||||||
|
|
||||||
|
//ACT
|
||||||
|
//stage executeClearing(startClearing)
|
||||||
|
addRecordToKafka((MockConsumer) eventsReceiver.getConsumer(), TOPIC_START_CLEARING, PARTITION, 0, getJsonStringForNew(new DealRegisterNewRequest(), ID));
|
||||||
|
|
||||||
|
//waiting for kafka producer send message
|
||||||
|
verify(mockProducer, timeout(230_000L).times(1))
|
||||||
|
.send(producerRecord.capture());
|
||||||
|
assertEquals(Consts.BALANCE_ACCOUNT_UPDATE, producerRecord.getValue().topic());
|
||||||
|
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
|
||||||
|
|
||||||
|
//stage continueClearing
|
||||||
|
CommonIdRequest requestPayload = new CommonIdRequest();
|
||||||
|
requestPayload.setId(baseRequestResult.getId());
|
||||||
|
addRecordToKafka((MockConsumer) eventsReceiver.getConsumer(), TOPIC_CONTINUE_CLEARING, PARTITION, 0, getJsonStringForNew(requestPayload, ID));
|
||||||
|
|
||||||
|
//waiting for kafka producer send message (finale event)
|
||||||
|
verify(mockProducer, timeout(230_000L).times(2))
|
||||||
|
.send(producerRecord.capture());
|
||||||
|
|
||||||
|
//ASSERT
|
||||||
|
assertEquals(Task.createOrder.topic(), producerRecord.getValue().topic());
|
||||||
|
|
||||||
|
//First LiabilitiesClaimsAssets && LiabilitiesClaimsMoney
|
||||||
|
LiabilitiesClaimsAssets resultFirstClaimsAssets = liabilitiesClaimsAssetsImdg.getSingleObjectByFieldValues(
|
||||||
|
Map.of("accountId", accountIdI1, "settlementDate", firstSettlementDateI1));
|
||||||
|
LiabilitiesClaimsMoney resultFirstClaimsMoney = liabilitiesClaimsMoneyImdg.getSingleObjectByFieldValues(
|
||||||
|
Map.of("accountId", accountIdI1, "settlementDate", firstSettlementDateI1));
|
||||||
|
LiabilitiesClaimsAssets predictableFirstClaimsAssets = lbltsClmsAssetsCreator.createFirstLegLCA(category, executionDeposit);
|
||||||
|
predictableFirstClaimsAssets.setId(resultFirstClaimsAssets.getId());
|
||||||
|
predictableFirstClaimsAssets.setPaymentId(resultFirstClaimsAssets.getPaymentId());
|
||||||
|
predictableFirstClaimsAssets.setLiabilitiesClaimsMoneyId(resultFirstClaimsMoney.getId());
|
||||||
|
LiabilitiesClaimsMoney predictableFirstClaimsMoney = lbltsClmsMoneyCreator.createFirstLegLcm(predictableFirstClaimsAssets, category);
|
||||||
|
predictableFirstClaimsMoney.setId(resultFirstClaimsMoney.getId());
|
||||||
|
LIABILITIES_CLAIMS_ASSETS_MATCHER.assertMatch(resultFirstClaimsAssets, predictableFirstClaimsAssets);
|
||||||
|
LIABILITIES_CLAIMS_MONEY_MATCHER.assertMatch(resultFirstClaimsMoney, predictableFirstClaimsMoney);
|
||||||
|
//Second LiabilitiesClaimsAssets && LiabilitiesClaimsMoney
|
||||||
|
LiabilitiesClaimsAssets resultSecondClaimsAssets = liabilitiesClaimsAssetsImdg.getSingleObjectByFieldValues(
|
||||||
|
Map.of("accountId", accountIdI1, "settlementDate", secondSettlementDateI2));
|
||||||
|
LiabilitiesClaimsMoney resultSecondClaimsMoney = liabilitiesClaimsMoneyImdg.getSingleObjectByFieldValues(
|
||||||
|
Map.of("accountId", accountIdI1, "settlementDate", secondSettlementDateI2));
|
||||||
|
LiabilitiesClaimsAssets predictableSecondClaimsAssets = lbltsClmsAssetsCreator.createSecondLegLCA(category, executionDeposit);
|
||||||
|
predictableSecondClaimsAssets.setId(resultSecondClaimsAssets.getId());
|
||||||
|
predictableSecondClaimsAssets.setLiabilitiesClaimsMoneyId(resultSecondClaimsMoney.getId());
|
||||||
|
LiabilitiesClaimsMoney predictableSecondClaimsMoney = lbltsClmsMoneyCreator.createSecondLegLcm(predictableSecondClaimsAssets, category);
|
||||||
|
predictableSecondClaimsMoney.setId(resultSecondClaimsMoney.getId());
|
||||||
|
LIABILITIES_CLAIMS_ASSETS_MATCHER.assertMatch(resultSecondClaimsAssets, predictableSecondClaimsAssets);
|
||||||
|
LIABILITIES_CLAIMS_MONEY_MATCHER.assertMatch(resultSecondClaimsMoney, predictableSecondClaimsMoney);
|
||||||
|
//PaymentInstruction
|
||||||
|
PaymentInstruction resultPaymentInstruction = paymentInstructionCreator.searchExistPaymentInstructionsFirstI(predictableFirstClaimsAssets);
|
||||||
|
PaymentInstruction predictablePaymentInstruction = paymentInstructionCreator.createPaymentInstruction(executionDeposit, predictableFirstClaimsAssets, Collections.singleton(category));
|
||||||
|
predictablePaymentInstruction.setId(resultPaymentInstruction.getId());
|
||||||
|
predictablePaymentInstruction.setDocumentNumber(resultPaymentInstruction.getDocumentNumber());
|
||||||
|
PAYMENT_INSTRUCTION_MATCHER.assertMatch(resultPaymentInstruction, predictablePaymentInstruction);
|
||||||
|
//ExecutionDeposit
|
||||||
|
ExecutionDeposit resultExecutionDeposit = executionDepositImdg.getSingleObjectByFieldValues(
|
||||||
|
Map.of("accountId", accountIdI1, "securityId", securityIdI1));
|
||||||
|
executionDeposit.setSessionId(resultExecutionDeposit.getSessionId());
|
||||||
|
EXECUTION_DEPOSIT_MATCHER.assertMatch(resultExecutionDeposit, executionDeposit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void preparOptimisticCase(Long companyId, Long relationId, Long accountId,
|
||||||
|
Long securityId, LocalDate dtF, LocalDate dtS, String memberCategory) {
|
||||||
|
category = IEnumKey.getEnumByKey(ClearingCategory.class, memberCategory);
|
||||||
|
|
||||||
|
executionDeposit = getExecutionDeposit(companyId, accountId, securityId, dtF, dtS);
|
||||||
|
executionDepositImdg.insert(executionDeposit);
|
||||||
|
|
||||||
|
ClearingMemberCategory clearingMemberCategory = new ClearingMemberCategory();
|
||||||
|
clearingMemberCategory.setCompanyId(companyId);
|
||||||
|
clearingMemberCategory.setClearingMemberCategory(memberCategory);
|
||||||
|
clearingCategoryImdg.insert(clearingMemberCategory);
|
||||||
|
|
||||||
|
Relation relation = new Relation();
|
||||||
|
relation.setId(relationId);
|
||||||
|
relation.setConsumerId(companyId);
|
||||||
|
relation.setServiceStatus(ServiceStatus.Active.getKey());
|
||||||
|
relationImdg.insert(relation);
|
||||||
|
|
||||||
|
Account account = new Account();
|
||||||
|
account.setId(accountId);
|
||||||
|
account.setRelationId(relationId);
|
||||||
|
account.setAccountStatus(AccountStatus.ACTIVE.getKey());
|
||||||
|
accountImdg.insert(account);
|
||||||
|
|
||||||
|
Company company = new Company();
|
||||||
|
company.setId(companyId);
|
||||||
|
company.setWorkflowStatus(WorkflowStatus.Active.getKey());
|
||||||
|
companyImdg.insert(company);
|
||||||
|
|
||||||
|
AccountBalance accountBalance = new AccountBalance();
|
||||||
|
accountBalance.setAccountId(accountId);
|
||||||
|
accountBalance.setCompanyId(companyId);
|
||||||
|
accountBalanceImdg.insert(accountBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecutionDeposit getExecutionDeposit(Long companyId, Long accountId, Long securityId, LocalDate dtF, LocalDate dtS) {
|
||||||
|
ExecutionDeposit executionDeposit = new ExecutionDeposit();
|
||||||
|
executionDeposit.setExchangeExecutionId(5L);
|
||||||
|
executionDeposit.setExchangeExecutionTime(Instant.now());
|
||||||
|
executionDeposit.setTradingDate(LocalDate.now());
|
||||||
|
executionDeposit.setAccountId(accountId);
|
||||||
|
executionDeposit.setMarket("market");
|
||||||
|
executionDeposit.setPrice(new BigDecimal(9));
|
||||||
|
executionDeposit.setLots(new BigDecimal(0));
|
||||||
|
executionDeposit.setQuantity(new BigDecimal(8));
|
||||||
|
executionDeposit.setFirstLegAmount(new BigDecimal(7));
|
||||||
|
executionDeposit.setSecondLegAmount(new BigDecimal(6));
|
||||||
|
executionDeposit.setInterestAmount(new BigDecimal(5));
|
||||||
|
executionDeposit.setSide("side");
|
||||||
|
executionDeposit.setSettlementCurrency("settlement");
|
||||||
|
executionDeposit.setCompanyId(companyId);
|
||||||
|
executionDeposit.setDuration(1L);
|
||||||
|
executionDeposit.setFirstLegSettlementDate(dtF);
|
||||||
|
executionDeposit.setSecondLegSettlementDate(dtS);
|
||||||
|
executionDeposit.setFirstLegSettlementCode(LocalDate.now());
|
||||||
|
executionDeposit.setSecondLegSettlementCode(LocalDate.now());
|
||||||
|
executionDeposit.setSecurityFullName("full");
|
||||||
|
executionDeposit.setSecuritySymbol("symbol");
|
||||||
|
executionDeposit.setSecurityId(securityId);
|
||||||
|
executionDeposit.setCounterPartyId(0L);
|
||||||
|
executionDeposit.setCoverageStatus(Allowed.ALLOWED.getKey());
|
||||||
|
executionDeposit.setSessionId(null);
|
||||||
|
executionDeposit.setClearingDate(LocalDate.now());
|
||||||
|
return executionDeposit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package ru.spcex.clearing.utils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for creating test matchers.
|
||||||
|
* <p>
|
||||||
|
* Comparing actual and expected objects via AssertJ
|
||||||
|
*/
|
||||||
|
public class MatcherFactory {
|
||||||
|
|
||||||
|
public static <T> Matcher<T> usingIgnoringFieldsComparator(String... fieldsToIgnore) {
|
||||||
|
return new Matcher<>(fieldsToIgnore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Matcher<T> {
|
||||||
|
private final String[] fieldsToIgnore;
|
||||||
|
|
||||||
|
private Matcher(String... fieldsToIgnore) {
|
||||||
|
this.fieldsToIgnore = fieldsToIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertMatch(T actual, T expected) {
|
||||||
|
assertThat(actual).usingRecursiveComparison().ignoringFields(fieldsToIgnore).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final void assertMatch(Iterable<T> actual, T... expected) {
|
||||||
|
assertMatch(actual, Arrays.asList(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertMatch(Iterable<T> actual, Iterable<T> expected) {
|
||||||
|
assertThat(actual).usingRecursiveFieldByFieldElementComparatorIgnoringFields(fieldsToIgnore).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
package ru.spcex.clearing.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
|
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||||
|
import org.apache.kafka.clients.producer.MockProducer;
|
||||||
|
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||||
|
import org.apache.kafka.clients.producer.RecordMetadata;
|
||||||
|
import org.apache.kafka.common.TopicPartition;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||||
|
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
||||||
|
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||||
|
import ru.spcex.clearing.service.builder.PaymentInstructionCreator;
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
|
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.timeout;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static ru.spcex.clearing.platform.messaging.service.Status.Success;
|
||||||
|
import static ru.spcex.clearing.utils.MatcherFactory.usingIgnoringFieldsComparator;
|
||||||
|
|
||||||
|
public class TestUtils {
|
||||||
|
public static final MatcherFactory.Matcher<BaseRequest<Object>> BASE_REQUEST_MATCHER = usingIgnoringFieldsComparator();
|
||||||
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
public static void waitingWhenAddedRecordAndCheckIt(Long id, MockProducer mockProducer, ArgumentCaptor<ProducerRecord> producerRecord) {
|
||||||
|
BaseRequest<Object> predictableBaseRequest = new BaseRequest<>();
|
||||||
|
predictableBaseRequest.setId(id);
|
||||||
|
predictableBaseRequest.setActionType(ActionType.SYSTEM);
|
||||||
|
RequestInfoUpdate requestInfoUpdate = new RequestInfoUpdate();
|
||||||
|
requestInfoUpdate.setId(id);
|
||||||
|
requestInfoUpdate.setStatus(Success);
|
||||||
|
predictableBaseRequest.setRequestPayload(requestInfoUpdate);
|
||||||
|
|
||||||
|
//waiting for kafka producer send message (finale event)
|
||||||
|
verify(mockProducer, timeout(30_000L).times(1))
|
||||||
|
.send(producerRecord.capture());
|
||||||
|
|
||||||
|
BaseRequest<Object> baseRequestResult = (BaseRequest<Object>) producerRecord.getValue().value();
|
||||||
|
assertEquals(Consts.REQUEST_INFO_UPDATE, producerRecord.getValue().topic());
|
||||||
|
BASE_REQUEST_MATCHER.assertMatch(baseRequestResult, predictableBaseRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addRecordToKafka(MockConsumer mockConsumer, String topic, int partition, long offset, String jsonValue) {
|
||||||
|
TopicPartition tp = new TopicPartition(topic, partition);
|
||||||
|
HashMap<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 clearAllInImdg(Imdg<T> imdg) {
|
||||||
|
Collection<T> values = imdg.getAllValues();
|
||||||
|
values.forEach(imdg::delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PaymentInstructionCreatorTest extends PaymentInstructionCreator {
|
||||||
|
public PaymentInstructionCreatorTest(ImdgProvider imdgProvider) {
|
||||||
|
super(imdgProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaymentInstruction createPaymentInstruction(ExecutionDeposit executionDeposit, LiabilitiesClaimsAssets liabilitiesClaimsAssets,
|
||||||
|
Collection<ClearingCategory> clearingCategory) {
|
||||||
|
List<PaymentInstruction> list = super.createPaymentInstructions(executionDeposit, liabilitiesClaimsAssets, clearingCategory);
|
||||||
|
return list.stream().findFirst().orElseGet(PaymentInstruction::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue