Merge remote-tracking branch 'origin/mivanov' into dev
# Conflicts: # clearing-parent/utility-service/pom.xml # platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/KeyRateNewRequest.java
This commit is contained in:
commit
5427c37028
11 changed files with 1149 additions and 0 deletions
|
|
@ -40,6 +40,46 @@
|
|||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>4.8.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package ru.spcex.clearing.securities.config;
|
||||
|
||||
import com.hazelcast.client.HazelcastClient;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class HazelcastInstanceTestConfiguration {
|
||||
|
||||
@Bean(name = "hazelcastInstance")
|
||||
public HazelcastInstance hazelcastInstance() {
|
||||
return HazelcastClient.newHazelcastClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package ru.spcex.clearing.securities.config;
|
||||
|
||||
import com.hazelcast.config.*;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@Configuration
|
||||
public class HazelcastServiceTestConfiguration {
|
||||
private HazelcastInstance hazelcastInstance;
|
||||
|
||||
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
|
||||
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
|
||||
if (maxPoolSz > 2) {
|
||||
pool.setKeepAliveSeconds(60);
|
||||
pool.setAllowCoreThreadTimeOut(true);
|
||||
}
|
||||
pool.setCorePoolSize(maxPoolSz);
|
||||
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
|
||||
return pool;
|
||||
}
|
||||
|
||||
@Bean(name = "hazelcastServiceTest")
|
||||
public HazelcastService hazelcastService(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, HazelcastClientParams params) {
|
||||
Config cfg = new Config();
|
||||
cfg.setInstanceName("localhost");
|
||||
|
||||
NetworkConfig networkConfig = new NetworkConfig();
|
||||
JoinConfig joinConfig = new JoinConfig();
|
||||
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
|
||||
joinConfig.setTcpIpConfig(new TcpIpConfig().
|
||||
setEnabled(true).setMembers(List.of("127.0.0.1")));
|
||||
networkConfig.setJoin(joinConfig);
|
||||
|
||||
cfg.setNetworkConfig(networkConfig);
|
||||
hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
|
||||
|
||||
HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance);
|
||||
return new HazelcastService(taskExecutorHazelcastClientInitializer,
|
||||
taskExecutorIdGeneratorAwaiter, params);
|
||||
}
|
||||
|
||||
@Bean(name = "taskExecutorHazelcastClientInitializer")
|
||||
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
|
||||
return createThreadPoolTaskExecutor(1, true);
|
||||
}
|
||||
|
||||
@Bean(name = "taskExecutorIdGeneratorAwaiter")
|
||||
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
|
||||
return createThreadPoolTaskExecutor(1, false);
|
||||
}
|
||||
|
||||
@Bean(name = "hazelcastClientParams")
|
||||
public HazelcastClientParams getHazelcastClientParams() {
|
||||
HazelcastClientParams params = new HazelcastClientParams();
|
||||
params.setLogin("dev");
|
||||
params.setPassword("dev-pass");
|
||||
params.setClusterMembers("127.0.0.1");
|
||||
params.setInstanceName("hzTestClient" + new Random().nextInt());
|
||||
params.setNearCacheConfig(new NearCacheConfig());
|
||||
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
package ru.spcex.clearing.securities.service;
|
||||
|
||||
import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
class MoneyMarketSecurityFactory {
|
||||
private Long id = 0L;
|
||||
private Long securityId = 0L;// (linked to security)
|
||||
private String description = "tsetse";
|
||||
private Double lotSize = 1.0;
|
||||
private Instant startDate = Instant.ofEpochSecond(0);
|
||||
private Instant endDate = Instant.ofEpochSecond(0);
|
||||
private BigDecimal nominalValue = BigDecimal.valueOf(1.0);
|
||||
|
||||
private Long nominalCurrency = 1L; // (linked to currencyCode)
|
||||
private String instrumentType = "sdgaga"; // (linked to instrumentType)
|
||||
private String fullName = "estat";
|
||||
|
||||
private Long nominalCurrencyId = 1L;
|
||||
private String securitySymbol = "sdfafd";
|
||||
|
||||
public MoneyMarketSecurityFactory setLotSize(Double lotSize) {
|
||||
this.lotSize = lotSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setNominalCurrencyId(Long nominalCurrencyId) {
|
||||
this.nominalCurrencyId = nominalCurrencyId;
|
||||
this.nominalCurrency = nominalCurrencyId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setId(Long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setSecurityId(Long securityId) {
|
||||
this.securityId = securityId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setStartDate(Instant startDate) {
|
||||
this.startDate = startDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setEndDate(Instant endDate) {
|
||||
this.endDate = endDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setNominalValue(BigDecimal nominalValue) {
|
||||
this.nominalValue = nominalValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setNominalCurrency(Long nominalCurrency) {
|
||||
this.nominalCurrency = nominalCurrency;
|
||||
this.nominalCurrencyId = nominalCurrency;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setInstrumentType(String instrumentType) {
|
||||
this.instrumentType = instrumentType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityFactory setSecuritySymbol(String securitySymbol) {
|
||||
this.securitySymbol = securitySymbol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurity getMoneyMarketSecurity() {
|
||||
MoneyMarketSecurity moneyMarketSecurity = new MoneyMarketSecurity();
|
||||
|
||||
moneyMarketSecurity.setId(id);
|
||||
moneyMarketSecurity.setSecurityId(securityId);
|
||||
moneyMarketSecurity.setDescription(description);
|
||||
moneyMarketSecurity.setStartDate(startDate.minusSeconds(60 * 60 * 3));
|
||||
moneyMarketSecurity.setEndDate(endDate.minusSeconds(60 * 60 * 3));
|
||||
moneyMarketSecurity.setNominalValue(nominalValue);
|
||||
moneyMarketSecurity.setNominalCurrency(nominalCurrency);
|
||||
moneyMarketSecurity.setInstrumentType(instrumentType);
|
||||
moneyMarketSecurity.setFullName(fullName);
|
||||
moneyMarketSecurity.setSecuritySymbol(securitySymbol);
|
||||
|
||||
return moneyMarketSecurity;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityUpdateRequest getMoneyMarketSecurityUpdateRequest() {
|
||||
MoneyMarketSecurityUpdateRequest moneyMarketSecurityUpdateRequest
|
||||
= new MoneyMarketSecurityUpdateRequest();
|
||||
|
||||
moneyMarketSecurityUpdateRequest.setId(id);
|
||||
moneyMarketSecurityUpdateRequest.setEndDate(endDate);
|
||||
moneyMarketSecurityUpdateRequest.setNominalValue(nominalValue.doubleValue());
|
||||
moneyMarketSecurityUpdateRequest.setNominalCurrencyId(nominalCurrencyId);
|
||||
moneyMarketSecurityUpdateRequest.setInstrumentType(instrumentType);
|
||||
moneyMarketSecurityUpdateRequest.setFullName(fullName);
|
||||
|
||||
return moneyMarketSecurityUpdateRequest;
|
||||
}
|
||||
|
||||
public CommonDeleteRequest getCommonDeleteRequest() {
|
||||
CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest();
|
||||
commonDeleteRequest.setId(id);
|
||||
return commonDeleteRequest;
|
||||
}
|
||||
|
||||
public MoneyMarketSecurityNewRequest getMoneyMarketSecurityNewRequest() {
|
||||
MoneyMarketSecurityNewRequest keyRequest = new MoneyMarketSecurityNewRequest();
|
||||
|
||||
keyRequest.setLotSize(lotSize);
|
||||
keyRequest.setStartDate(startDate);
|
||||
keyRequest.setEndDate(endDate);
|
||||
keyRequest.setNominalValue(nominalValue.doubleValue());
|
||||
keyRequest.setNominalCurrencyId(nominalCurrencyId);
|
||||
keyRequest.setInstrumentType(instrumentType);
|
||||
keyRequest.setFullName(fullName);
|
||||
keyRequest.setSecuritySymbol(securitySymbol);
|
||||
|
||||
return keyRequest;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
package ru.spcex.clearing.securities.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.core.IMap;
|
||||
import com.hazelcast.map.listener.EntryAddedListener;
|
||||
import com.hazelcast.map.listener.EntryRemovedListener;
|
||||
import com.hazelcast.map.listener.EntryUpdatedListener;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
|
||||
import org.apache.kafka.common.TopicPartition;
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.clearing.classes.statics.data.misc.KeyRate;
|
||||
import ru.clearing.classes.statics.data.misc.MoneyMarketSecurity;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityUpdateRequest;
|
||||
import ru.spcex.clearing.securities.config.HazelcastInstanceTestConfiguration;
|
||||
import ru.spcex.clearing.securities.config.HazelcastServiceTestConfiguration;
|
||||
import ru.spcex.clearing.securities.service.cud.MoneyMarketSecurityService;
|
||||
import ru.spcex.clearing.securities.utils.MatcherFactory;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
HazelcastServiceTestConfiguration.class,
|
||||
HazelcastInstanceTestConfiguration.class})
|
||||
public class MoneyMarketSecurityServiceTest {
|
||||
static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final int TIMEOUT = 1000;
|
||||
boolean isUsed;
|
||||
private MockConsumer<String, Object> kafkaMockQueue;
|
||||
@Autowired
|
||||
@Qualifier("hazelcastServiceTest")
|
||||
private HazelcastService hazelcastService;
|
||||
@Autowired
|
||||
@Qualifier("hazelcastInstance")
|
||||
private HazelcastInstance hz;
|
||||
|
||||
private void setIsUsed(boolean isUsed) {
|
||||
this.isUsed = isUsed;
|
||||
}
|
||||
|
||||
private String jsonBaseRequest(BaseRequest baseRequest) {
|
||||
String jsonBaseRequest;
|
||||
|
||||
try {
|
||||
jsonBaseRequest = objectMapper.writeValueAsString(baseRequest);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return jsonBaseRequest;
|
||||
}
|
||||
|
||||
void initKafka(String topic, int partition, Long offset) {
|
||||
TopicPartition tp = new TopicPartition(topic, partition);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> {
|
||||
kafkaMockQueue.rebalance(Collections.singletonList(tp));
|
||||
});
|
||||
|
||||
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
|
||||
startOffsets.put(tp, offset);
|
||||
|
||||
kafkaMockQueue.updateBeginningOffsets(startOffsets);
|
||||
}
|
||||
|
||||
private void startService() throws InterruptedException {
|
||||
MoneyMarketSecurityService keyRateService =
|
||||
new MoneyMarketSecurityService(kafkaMockQueue, hazelcastService);
|
||||
keyRateService.afterPropertiesSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MoneyMarketSecurityService#newMoneyMarket(BaseRequest)}<br>
|
||||
* Тест проверяет генерацию сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.<br>
|
||||
* Входной запрос {@link MoneyMarketSecurityNewRequest}:<br>
|
||||
* {@link MoneyMarketSecurityNewRequest#lotSize} - 1.0<br>
|
||||
* {@link MoneyMarketSecurityNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.<br>
|
||||
* {@link MoneyMarketSecurityNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.<br>
|
||||
* {@link MoneyMarketSecurityNewRequest#nominalValue} - 1.0<br>
|
||||
* {@link MoneyMarketSecurityNewRequest#nominalCurrencyId} - 1L<br>
|
||||
* {@link MoneyMarketSecurityNewRequest#instrumentType} - "sdgaga"<br>
|
||||
* {@link MoneyMarketSecurityNewRequest#fullName} - "estat"<br>
|
||||
*/
|
||||
@Test
|
||||
public void testNewMoneyMarketSecurity() throws InterruptedException {
|
||||
final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW;
|
||||
final String MAP = IMDGDistributedNames.Map_MoneyMarketSecurity;
|
||||
|
||||
final int PARTITION = 0;
|
||||
final Long OFFSET = 0L;
|
||||
final Long REQUEST_ID = 0L;
|
||||
|
||||
final MoneyMarketSecurityFactory moneyMarketSecurityFactory = new MoneyMarketSecurityFactory();
|
||||
|
||||
final MoneyMarketSecurity moneyMarketSecurityPrediction = moneyMarketSecurityFactory
|
||||
.getMoneyMarketSecurity();
|
||||
final MoneyMarketSecurityNewRequest keyRequest = moneyMarketSecurityFactory
|
||||
.getMoneyMarketSecurityNewRequest();
|
||||
|
||||
BaseRequest baseRequest = new BaseRequest();
|
||||
|
||||
baseRequest.setRequestPayload(keyRequest);
|
||||
baseRequest.setId(REQUEST_ID);
|
||||
baseRequest.setActionType(ActionType.NEW);
|
||||
|
||||
String jsonRequest = jsonBaseRequest(baseRequest);
|
||||
|
||||
ConsumerRecord<String, Object> consumerRecord =
|
||||
new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest);
|
||||
|
||||
kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
initKafka(TOPIC, PARTITION, OFFSET);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord));
|
||||
|
||||
isUsed = false;
|
||||
|
||||
IMap<Long, MoneyMarketSecurity> iMap = hz.getMap(MAP);
|
||||
|
||||
Object waiter = new Object();
|
||||
|
||||
String listenerID = iMap.addEntryListener((EntryAddedListener<Long, MoneyMarketSecurity>) entryEvent -> {
|
||||
System.out.println("Checking Equality");
|
||||
MoneyMarketSecurity moneyMarketSecurityResult = entryEvent.getValue();
|
||||
moneyMarketSecurityPrediction.setId(entryEvent.getKey());
|
||||
|
||||
MatcherFactory.Matcher<MoneyMarketSecurity> matcher = MatcherFactory
|
||||
.usingIgnoringFieldsComparator("id", "securityId", "description");
|
||||
matcher.assertMatch(moneyMarketSecurityResult, moneyMarketSecurityPrediction);
|
||||
System.out.println("ok");
|
||||
setIsUsed(true);
|
||||
synchronized (waiter) {
|
||||
waiter.notify();
|
||||
}
|
||||
}, true);
|
||||
|
||||
startService();
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.wait(TIMEOUT);
|
||||
}
|
||||
|
||||
Assertions.assertEquals(true, isUsed);
|
||||
iMap.removeEntryListener(listenerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MoneyMarketSecurityService#deleteMoneyMarket(BaseRequest)}<br>
|
||||
* Тест проверяет удаление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.<br>
|
||||
* Входной запрос {@link CommonDeleteRequest}:<br>
|
||||
* {@link CommonDeleteRequest#id} - Идентификатор записи<br>
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteKeyRate() throws InterruptedException {
|
||||
final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_DELETE;
|
||||
final String MAP = IMDGDistributedNames.Map_MoneyMarketSecurity;
|
||||
|
||||
final int PARTITION = 0;
|
||||
final Long ID = 1L;
|
||||
final Long OFFSET = 0L;
|
||||
final Long REQUEST_ID = 2L;
|
||||
|
||||
final MoneyMarketSecurityFactory moneyMarketSecurityFactory =
|
||||
new MoneyMarketSecurityFactory()
|
||||
.setId(ID);
|
||||
|
||||
final MoneyMarketSecurity initialMoneyMarketSecurity = moneyMarketSecurityFactory
|
||||
.getMoneyMarketSecurity();
|
||||
final CommonDeleteRequest keyRequest = moneyMarketSecurityFactory
|
||||
.getCommonDeleteRequest();
|
||||
|
||||
BaseRequest baseRequest = new BaseRequest();
|
||||
|
||||
baseRequest.setRequestPayload(keyRequest);
|
||||
baseRequest.setId(REQUEST_ID);
|
||||
baseRequest.setActionType(ActionType.DELETE);
|
||||
|
||||
String jsonRequest = jsonBaseRequest(baseRequest);
|
||||
|
||||
ConsumerRecord<String, Object> consumerRecord =
|
||||
new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest);
|
||||
|
||||
kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
initKafka(TOPIC, PARTITION, OFFSET);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord));
|
||||
|
||||
isUsed = false;
|
||||
|
||||
IMap<Long, MoneyMarketSecurity> iMap = hz.getMap(MAP);
|
||||
iMap.put(ID, initialMoneyMarketSecurity);
|
||||
|
||||
Object waiter = new Object();
|
||||
String listenerID = iMap.addEntryListener((EntryRemovedListener<Long, KeyRate>) entryEvent -> {
|
||||
System.out.println("Checking If removed..");
|
||||
Assertions.assertEquals(ID, entryEvent.getKey());
|
||||
System.out.println("ok");
|
||||
setIsUsed(true);
|
||||
synchronized (waiter) {
|
||||
waiter.notify();
|
||||
}
|
||||
}, false);
|
||||
|
||||
startService();
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.wait(TIMEOUT);
|
||||
}
|
||||
|
||||
Assertions.assertEquals(true, isUsed);
|
||||
iMap.removeEntryListener(listenerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MoneyMarketSecurityService#updateMoneyMarket(BaseRequest)}
|
||||
* Тест проверяет обновление сущности {@link MoneyMarketSecurity} в Hazelcast при передаче из Apache Kafka.<br>
|
||||
* Входной запрос {@link MoneyMarketSecurityUpdateRequest}:<br>
|
||||
* {@link MoneyMarketSecurityUpdateRequest#fullName} - sfgsdfg<br>
|
||||
* {@link MoneyMarketSecurityUpdateRequest#instrumentType} - qwerqwe<br>
|
||||
* {@link MoneyMarketSecurityUpdateRequest#nominalCurrencyId} - 2L<br>
|
||||
* {@link MoneyMarketSecurityUpdateRequest#nominalValue} - 2.0<br>
|
||||
* {@link MoneyMarketSecurityUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)<br>
|
||||
*/
|
||||
@Test
|
||||
public void testUpdateKeyRate() throws InterruptedException {
|
||||
final String TOPIC = Consts.DESTINATION_MONEY_MARKET_SECURITY_UPDATE;
|
||||
final String MAP = IMDGDistributedNames.Map_MoneyMarketSecurity;
|
||||
|
||||
final int PARTITION = 0;
|
||||
final Long ID = 1L;
|
||||
final Long OFFSET = 0L;
|
||||
final Long REQUEST_ID = 1L;
|
||||
|
||||
final MoneyMarketSecurityFactory moneyMarketSecurityFactory =
|
||||
new MoneyMarketSecurityFactory()
|
||||
.setId(ID);
|
||||
|
||||
final MoneyMarketSecurity initialMoneyMarketSecurity = moneyMarketSecurityFactory
|
||||
.getMoneyMarketSecurity();
|
||||
|
||||
moneyMarketSecurityFactory
|
||||
.setFullName("sfgsdfg")
|
||||
.setInstrumentType("qwerqwe")
|
||||
.setNominalCurrencyId(2L)
|
||||
.setNominalValue(BigDecimal.valueOf(2.0))
|
||||
.setEndDate(Instant.ofEpochSecond(24 * 3600));
|
||||
|
||||
final MoneyMarketSecurity moneyMarketSecurityPrediction =
|
||||
moneyMarketSecurityFactory.getMoneyMarketSecurity();
|
||||
final MoneyMarketSecurityUpdateRequest keyRequest =
|
||||
moneyMarketSecurityFactory.getMoneyMarketSecurityUpdateRequest();
|
||||
|
||||
BaseRequest baseRequest = new BaseRequest();
|
||||
|
||||
baseRequest.setRequestPayload(keyRequest);
|
||||
baseRequest.setId(REQUEST_ID);
|
||||
baseRequest.setActionType(ActionType.UPDATE);
|
||||
|
||||
String jsonRequest = jsonBaseRequest(baseRequest);
|
||||
|
||||
ConsumerRecord<String, Object> consumerRecord =
|
||||
new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest);
|
||||
|
||||
kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
initKafka(TOPIC, PARTITION, OFFSET);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord));
|
||||
|
||||
IMap<Long, MoneyMarketSecurity> iMap = hz.getMap(MAP);
|
||||
iMap.put(ID, initialMoneyMarketSecurity);
|
||||
|
||||
isUsed = false;
|
||||
|
||||
Object waiter = new Object();
|
||||
String listenerID = iMap.addEntryListener((EntryUpdatedListener<Long, MoneyMarketSecurity>) entryEvent -> {
|
||||
System.out.println("Checking Equality..");
|
||||
MoneyMarketSecurity moneyMarketSecurityResult = entryEvent.getValue();
|
||||
|
||||
MatcherFactory.Matcher<MoneyMarketSecurity> matcher = MatcherFactory
|
||||
.usingIgnoringFieldsComparator("id");
|
||||
|
||||
matcher.assertMatch(moneyMarketSecurityResult, moneyMarketSecurityPrediction);
|
||||
|
||||
System.out.println("Ok");
|
||||
setIsUsed(true);
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.notify();
|
||||
}
|
||||
}, true);
|
||||
|
||||
startService();
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.wait(TIMEOUT);
|
||||
}
|
||||
|
||||
Assertions.assertEquals(true, isUsed);
|
||||
iMap.removeEntryListener(listenerID);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package ru.spcex.clearing.securities.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,23 @@
|
|||
package ru.spcex.clearing.utility.config;
|
||||
|
||||
import com.hazelcast.client.HazelcastClient;
|
||||
import com.hazelcast.config.Config;
|
||||
import com.hazelcast.config.JoinConfig;
|
||||
import com.hazelcast.config.MulticastConfig;
|
||||
import com.hazelcast.config.NetworkConfig;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@Configuration
|
||||
public class HazelcastInstanceTestConfiguration {
|
||||
|
||||
@Bean(name = "hazelcastInstance")
|
||||
public HazelcastInstance hazelcastInstance() {
|
||||
return HazelcastClient.newHazelcastClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package ru.spcex.clearing.utility.config;
|
||||
|
||||
import com.hazelcast.config.*;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.util.HazelcastHelper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@Configuration
|
||||
public class HazelcastServiceTestConfiguration {
|
||||
private HazelcastInstance hazelcastInstance;
|
||||
|
||||
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
|
||||
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
|
||||
if (maxPoolSz > 2) {
|
||||
pool.setKeepAliveSeconds(60);
|
||||
pool.setAllowCoreThreadTimeOut(true);
|
||||
}
|
||||
pool.setCorePoolSize(maxPoolSz);
|
||||
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
|
||||
return pool;
|
||||
}
|
||||
|
||||
@Bean(name = "hazelcastServiceTest")
|
||||
public HazelcastService hazelcastService(@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, HazelcastClientParams params) {
|
||||
Config cfg = new Config();
|
||||
cfg.setInstanceName("localhost");
|
||||
|
||||
NetworkConfig networkConfig = new NetworkConfig();
|
||||
JoinConfig joinConfig = new JoinConfig();
|
||||
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
|
||||
joinConfig.setTcpIpConfig(new TcpIpConfig().
|
||||
setEnabled(true).setMembers(List.of("127.0.0.1")));
|
||||
networkConfig.setJoin(joinConfig);
|
||||
|
||||
cfg.setNetworkConfig(networkConfig);
|
||||
hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
|
||||
|
||||
HazelcastHelper.otcSystem_setStorageState(true, hazelcastInstance);
|
||||
return new HazelcastService(taskExecutorHazelcastClientInitializer,
|
||||
taskExecutorIdGeneratorAwaiter, params);
|
||||
}
|
||||
|
||||
@Bean(name = "taskExecutorHazelcastClientInitializer")
|
||||
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
|
||||
return createThreadPoolTaskExecutor(1, true);
|
||||
}
|
||||
|
||||
@Bean(name = "taskExecutorIdGeneratorAwaiter")
|
||||
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
|
||||
return createThreadPoolTaskExecutor(1, false);
|
||||
}
|
||||
|
||||
@Bean(name = "hazelcastClientParams")
|
||||
public HazelcastClientParams getHazelcastClientParams() {
|
||||
HazelcastClientParams params = new HazelcastClientParams();
|
||||
params.setLogin("dev");
|
||||
params.setPassword("dev-pass");
|
||||
params.setClusterMembers("127.0.0.1");
|
||||
params.setInstanceName("hzTestClient" + new Random().nextInt());
|
||||
params.setNearCacheConfig(new NearCacheConfig());
|
||||
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package ru.spcex.clearing.utility.service;
|
||||
|
||||
import ru.clearing.classes.statics.data.misc.KeyRate;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.KeyRateNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.KeyRateUpdateRequest;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
class KeyRateFactory {
|
||||
Instant startDate = Instant.ofEpochSecond(0);
|
||||
Instant endDate = Instant.ofEpochSecond(0);
|
||||
String document = "Test";
|
||||
double rate = 0.5;
|
||||
|
||||
Long id = 0L;
|
||||
|
||||
KeyRateFactory setRate(double rate) {
|
||||
this.rate = rate;
|
||||
return this;
|
||||
}
|
||||
|
||||
KeyRateFactory setEndDate(Instant endDate) {
|
||||
this.endDate = endDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
KeyRateFactory setId(Long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
KeyRateFactory setDocument(String document) {
|
||||
this.document = document;
|
||||
return this;
|
||||
}
|
||||
|
||||
KeyRateFactory setStartDate(Instant startDate) {
|
||||
this.startDate = startDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public KeyRate getKeyRate() {
|
||||
KeyRate keyRatePrediction = new KeyRate();
|
||||
keyRatePrediction.setId(id);
|
||||
keyRatePrediction.setDocument(document);
|
||||
keyRatePrediction.setEndDate(endDate.minusSeconds(60 * 60 * 3));
|
||||
keyRatePrediction.setStartDate(startDate.minusSeconds(60 * 60 * 3));
|
||||
keyRatePrediction.setRate(rate);
|
||||
return keyRatePrediction;
|
||||
}
|
||||
|
||||
public KeyRateUpdateRequest getKeyRateUpdateRequest() {
|
||||
KeyRateUpdateRequest keyRateUpdateRequest = new KeyRateUpdateRequest();
|
||||
|
||||
keyRateUpdateRequest.setId(id);
|
||||
keyRateUpdateRequest.setKeyRate(rate);
|
||||
keyRateUpdateRequest.setDocument(document);
|
||||
keyRateUpdateRequest.setStartDate(startDate);
|
||||
keyRateUpdateRequest.setEndDate(endDate);
|
||||
|
||||
return keyRateUpdateRequest;
|
||||
}
|
||||
|
||||
public CommonDeleteRequest getCommonDeleteRequest() {
|
||||
CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest();
|
||||
commonDeleteRequest.setId(id);
|
||||
return commonDeleteRequest;
|
||||
}
|
||||
|
||||
public KeyRateNewRequest getKeyRateNewRequest() {
|
||||
KeyRateNewRequest keyRequest = new KeyRateNewRequest();
|
||||
keyRequest.setKeyRate(rate);
|
||||
keyRequest.setDocument(document);
|
||||
keyRequest.setEndDate(endDate);
|
||||
keyRequest.setStartDate(startDate);
|
||||
return keyRequest;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
package ru.spcex.clearing.utility.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
import com.hazelcast.core.IMap;
|
||||
import com.hazelcast.map.listener.EntryAddedListener;
|
||||
import com.hazelcast.map.listener.EntryRemovedListener;
|
||||
import com.hazelcast.map.listener.EntryUpdatedListener;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.consumer.OffsetResetStrategy;
|
||||
import org.apache.kafka.common.TopicPartition;
|
||||
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.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.clearing.classes.statics.data.misc.KeyRate;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.KeyRateNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.KeyRateUpdateRequest;
|
||||
import ru.spcex.clearing.utility.config.HazelcastInstanceTestConfiguration;
|
||||
import ru.spcex.clearing.utility.config.HazelcastServiceTestConfiguration;
|
||||
import ru.spcex.clearing.utility.utils.MatcherFactory;
|
||||
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
HazelcastServiceTestConfiguration.class,
|
||||
HazelcastInstanceTestConfiguration.class})
|
||||
public class KeyRateServiceTest {
|
||||
static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final int TIMEOUT = 1000;
|
||||
boolean isUsed;
|
||||
private MockConsumer<String, Object> kafkaMockQueue;
|
||||
@Autowired
|
||||
@Qualifier("hazelcastServiceTest")
|
||||
private HazelcastService hazelcastService;
|
||||
@Autowired
|
||||
@Qualifier("hazelcastInstance")
|
||||
private HazelcastInstance hz;
|
||||
|
||||
private void setIsUsed(boolean isUsed) {
|
||||
this.isUsed = isUsed;
|
||||
}
|
||||
|
||||
private String jsonBaseRequest(BaseRequest baseRequest) {
|
||||
String jsonBaseRequest;
|
||||
|
||||
try {
|
||||
jsonBaseRequest = objectMapper.writeValueAsString(baseRequest);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return jsonBaseRequest;
|
||||
}
|
||||
|
||||
void initKafka(String topic, int partition, Long offset) {
|
||||
TopicPartition tp = new TopicPartition(topic, partition);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> {
|
||||
kafkaMockQueue.rebalance(Collections.singletonList(tp));
|
||||
});
|
||||
|
||||
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
|
||||
startOffsets.put(tp, offset);
|
||||
|
||||
kafkaMockQueue.updateBeginningOffsets(startOffsets);
|
||||
}
|
||||
|
||||
private void startService() throws InterruptedException {
|
||||
KeyRateService keyRateService =
|
||||
new KeyRateService(kafkaMockQueue, hazelcastService);
|
||||
keyRateService.afterPropertiesSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link KeyRateService#newKeyRate(BaseRequest)}
|
||||
* Тест проверяет генерацию сущности {@link KeyRate} в Hazelcast при передаче из Apache Kafka.<br>
|
||||
* Входной запрос {@link KeyRateNewRequest}:<br>
|
||||
* {@link KeyRateNewRequest#keyRate} - 0.5<br>
|
||||
* {@link KeyRateNewRequest#document} - "Test"<br>
|
||||
* {@link KeyRateNewRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.<br>
|
||||
* {@link KeyRateNewRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z.<br>
|
||||
*/
|
||||
@Test
|
||||
public void testNewKeyRate() throws InterruptedException {
|
||||
final String TOPIC = Consts.DESTINATION_KEY_RATE_NEW;
|
||||
final String MAP = IMDGDistributedNames.Map_KeyRate;
|
||||
|
||||
final int PARTITION = 0;
|
||||
final Long OFFSET = 0L;
|
||||
final Long REQUEST_ID = 0L;
|
||||
|
||||
final KeyRateFactory keyRateFactory = new KeyRateFactory();
|
||||
|
||||
final KeyRate keyRatePrediction = keyRateFactory.getKeyRate();
|
||||
final KeyRateNewRequest keyRequest = keyRateFactory.getKeyRateNewRequest();
|
||||
|
||||
BaseRequest baseRequest = new BaseRequest();
|
||||
|
||||
baseRequest.setRequestPayload(keyRequest);
|
||||
baseRequest.setId(REQUEST_ID);
|
||||
baseRequest.setActionType(ActionType.NEW);
|
||||
|
||||
String jsonRequest = jsonBaseRequest(baseRequest);
|
||||
|
||||
ConsumerRecord<String, Object> consumerRecord =
|
||||
new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest);
|
||||
|
||||
kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
initKafka(TOPIC, PARTITION, OFFSET);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord));
|
||||
|
||||
|
||||
isUsed = false;
|
||||
|
||||
IMap<Long, KeyRate> iMap = hz.getMap(MAP);
|
||||
|
||||
Object waiter = new Object();
|
||||
|
||||
String listenerID = iMap.addEntryListener((EntryAddedListener<Long, KeyRate>) entryEvent -> {
|
||||
System.out.println("Checking Equality");
|
||||
KeyRate keyRateResult = entryEvent.getValue();
|
||||
keyRatePrediction.setId(entryEvent.getKey());
|
||||
|
||||
MatcherFactory.Matcher<KeyRate> matcher = MatcherFactory
|
||||
.usingIgnoringFieldsComparator("id");
|
||||
matcher.assertMatch(keyRateResult, keyRatePrediction);
|
||||
System.out.println("ok");
|
||||
setIsUsed(true);
|
||||
synchronized (waiter) {
|
||||
waiter.notify();
|
||||
}
|
||||
}, true);
|
||||
|
||||
startService();
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.wait(TIMEOUT);
|
||||
}
|
||||
|
||||
Assertions.assertEquals(true, isUsed);
|
||||
iMap.removeEntryListener(listenerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link KeyRateService#deleteKeyRate(BaseRequest)}<br>
|
||||
* Тест проверяет удаление сущности {@link KeyRate} в Hazelcast при передаче из Apache Kafka.<br>
|
||||
* Входной запрос {@link CommonDeleteRequest}:<br>
|
||||
* {@link CommonDeleteRequest#id} - Идентификатор записи<br>
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteKeyRate() throws InterruptedException {
|
||||
final String TOPIC = Consts.DESTINATION_KEY_RATE_DELETE;
|
||||
final String MAP = IMDGDistributedNames.Map_KeyRate;
|
||||
|
||||
final int PARTITION = 0;
|
||||
final Long ID = 1L;
|
||||
final Long OFFSET = 0L;
|
||||
final Long REQUEST_ID = 2L;
|
||||
|
||||
final KeyRateFactory keyRateFactory = new KeyRateFactory()
|
||||
.setId(ID);
|
||||
|
||||
final KeyRate initialKeyRate = keyRateFactory.getKeyRate();
|
||||
final CommonDeleteRequest keyRequest = keyRateFactory.getCommonDeleteRequest();
|
||||
|
||||
BaseRequest baseRequest = new BaseRequest();
|
||||
|
||||
baseRequest.setRequestPayload(keyRequest);
|
||||
baseRequest.setId(REQUEST_ID);
|
||||
baseRequest.setActionType(ActionType.DELETE);
|
||||
|
||||
String jsonRequest = jsonBaseRequest(baseRequest);
|
||||
|
||||
ConsumerRecord<String, Object> consumerRecord =
|
||||
new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest);
|
||||
|
||||
kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
initKafka(TOPIC, PARTITION, OFFSET);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord));
|
||||
|
||||
|
||||
isUsed = false;
|
||||
|
||||
IMap<Long, KeyRate> iMap = hz.getMap(MAP);
|
||||
iMap.put(ID, initialKeyRate);
|
||||
|
||||
Object waiter = new Object();
|
||||
String listenerID = iMap.addEntryListener((EntryRemovedListener<Long, KeyRate>) entryEvent -> {
|
||||
System.out.println("Checking If removed..");
|
||||
Assertions.assertEquals(ID, entryEvent.getKey());
|
||||
System.out.println("ok");
|
||||
setIsUsed(true);
|
||||
synchronized (waiter) {
|
||||
waiter.notify();
|
||||
}
|
||||
}, false);
|
||||
|
||||
startService();
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.wait(TIMEOUT);
|
||||
}
|
||||
|
||||
Assertions.assertEquals(true, isUsed);
|
||||
iMap.removeEntryListener(listenerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link KeyRateService#updateKeyRate(BaseRequest)}
|
||||
* Тест проверяет генерацию сущности {@link KeyRate} в Hazelcast при передаче из Apache Kafka.<br>
|
||||
* Входной запрос {@link KeyRateUpdateRequest}:<br>
|
||||
* {@link KeyRateUpdateRequest#keyRate} - 5<br>
|
||||
* {@link KeyRateUpdateRequest#document} - "Update"<br>
|
||||
* {@link KeyRateUpdateRequest#startDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)<br>
|
||||
* {@link KeyRateUpdateRequest#endDate} - текущее колличество секунд с 1970-01-01T00:00:00Z + (24 * 3600)<br>
|
||||
*/
|
||||
@Test
|
||||
public void testUpdateKeyRate() throws InterruptedException {
|
||||
final String TOPIC = Consts.DESTINATION_KEY_RATE_UPDATE;
|
||||
final String MAP = IMDGDistributedNames.Map_KeyRate;
|
||||
|
||||
final int PARTITION = 0;
|
||||
final Long ID = 1L;
|
||||
final Long OFFSET = 0L;
|
||||
final Long REQUEST_ID = 1L;
|
||||
|
||||
final KeyRateFactory keyRateFactory = new KeyRateFactory()
|
||||
.setId(ID);
|
||||
|
||||
final KeyRate initialKeyRate = keyRateFactory.getKeyRate();
|
||||
|
||||
keyRateFactory
|
||||
.setRate(5)
|
||||
.setEndDate(Instant.ofEpochSecond(24 * 3600))
|
||||
.setStartDate(Instant.ofEpochSecond(24 * 3600))
|
||||
.setDocument("Update");
|
||||
|
||||
final KeyRate keyRatePrediction = keyRateFactory.getKeyRate();
|
||||
final KeyRateUpdateRequest keyRequest = keyRateFactory.getKeyRateUpdateRequest();
|
||||
|
||||
BaseRequest baseRequest = new BaseRequest();
|
||||
|
||||
baseRequest.setRequestPayload(keyRequest);
|
||||
baseRequest.setId(REQUEST_ID);
|
||||
baseRequest.setActionType(ActionType.UPDATE);
|
||||
|
||||
String jsonRequest = jsonBaseRequest(baseRequest);
|
||||
|
||||
ConsumerRecord<String, Object> consumerRecord =
|
||||
new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", jsonRequest);
|
||||
|
||||
kafkaMockQueue = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
initKafka(TOPIC, PARTITION, OFFSET);
|
||||
|
||||
kafkaMockQueue.schedulePollTask(() -> kafkaMockQueue.addRecord(consumerRecord));
|
||||
|
||||
IMap<Long, KeyRate> iMap = hz.getMap(MAP);
|
||||
iMap.put(ID, initialKeyRate);
|
||||
|
||||
isUsed = false;
|
||||
|
||||
Object waiter = new Object();
|
||||
String listenerID = iMap.addEntryListener((EntryUpdatedListener<Long, KeyRate>) entryEvent -> {
|
||||
System.out.println("Checking Equality..");
|
||||
KeyRate keyRateResult = entryEvent.getValue();
|
||||
|
||||
MatcherFactory.Matcher<KeyRate> matcher = MatcherFactory
|
||||
.usingIgnoringFieldsComparator("id");
|
||||
|
||||
matcher.assertMatch(keyRateResult, keyRatePrediction);
|
||||
|
||||
System.out.println("Ok");
|
||||
setIsUsed(true);
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.notify();
|
||||
}
|
||||
}, true);
|
||||
|
||||
startService();
|
||||
|
||||
synchronized (waiter) {
|
||||
waiter.wait(TIMEOUT);
|
||||
}
|
||||
|
||||
Assertions.assertEquals(true, isUsed);
|
||||
iMap.removeEntryListener(listenerID);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package ru.spcex.clearing.utility.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue