parent
f8271d3ee2
commit
bf6ec283f7
1 changed files with 4 additions and 140 deletions
|
|
@ -1,8 +1,9 @@
|
||||||
package ru.spcex.clearing.account.service;
|
package ru.spcex.clearing.account.service;
|
||||||
|
|
||||||
import org.apache.kafka.clients.consumer.*;
|
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.apache.kafka.common.TopicPartition;
|
||||||
import org.apache.kafka.common.errors.WakeupException;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
@ -13,35 +14,20 @@ import ru.spcex.platform.imdg.api.Imdg;
|
||||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
|
import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
|
||||||
class BankAccountServiceTest {
|
class BankAccountServiceTest {
|
||||||
|
|
||||||
private static final int PARTITION = 0;
|
private static final int PARTITION = 0;
|
||||||
private static final String TOPIC = Consts.DESTINATION_BANK_ACCOUNT_NEW;
|
private static final String TOPIC = Consts.DESTINATION_BANK_ACCOUNT_NEW;
|
||||||
private MockConsumer<String, Integer> consumer;
|
|
||||||
private MockConsumer<String, Object> mockConsumer;
|
private MockConsumer<String, Object> mockConsumer;
|
||||||
private List updates;
|
|
||||||
private CountryPopulationConsumer countryPopulationConsumer;
|
|
||||||
private Throwable pollException;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
mockConsumer = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
mockConsumer = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||||
|
|
||||||
consumer = new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
|
||||||
updates = new ArrayList<>();
|
|
||||||
countryPopulationConsumer = new CountryPopulationConsumer(consumer,
|
|
||||||
ex -> this.pollException = ex, updates::add);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -49,7 +35,7 @@ class BankAccountServiceTest {
|
||||||
//arrange
|
//arrange
|
||||||
mockConsumer.schedulePollTask(() -> {
|
mockConsumer.schedulePollTask(() -> {
|
||||||
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC, PARTITION)));
|
mockConsumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC, PARTITION)));
|
||||||
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", "value"));
|
mockConsumer.addRecord(new ConsumerRecord<>(TOPIC, PARTITION, 0, "key", "test-value"));
|
||||||
});
|
});
|
||||||
mockConsumer.schedulePollTask(() -> mockConsumer.wakeup());
|
mockConsumer.schedulePollTask(() -> mockConsumer.wakeup());
|
||||||
|
|
||||||
|
|
@ -78,126 +64,4 @@ class BankAccountServiceTest {
|
||||||
//assert
|
//assert
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void whenStartingByAssigningTopicPartition_thenExpectUpdatesAreConsumedCorrectly() {
|
|
||||||
// GIVEN
|
|
||||||
consumer.schedulePollTask(() -> consumer.addRecord(record(TOPIC, PARTITION, "Romania", 19_410_000)));
|
|
||||||
consumer.schedulePollTask(() -> countryPopulationConsumer.stop());
|
|
||||||
|
|
||||||
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
|
|
||||||
TopicPartition tp = new TopicPartition(TOPIC, PARTITION);
|
|
||||||
startOffsets.put(tp, 0L);
|
|
||||||
consumer.updateBeginningOffsets(startOffsets);
|
|
||||||
|
|
||||||
// WHEN
|
|
||||||
countryPopulationConsumer.startByAssigning(TOPIC, PARTITION);
|
|
||||||
|
|
||||||
// THEN
|
|
||||||
assertThat(updates).hasSize(1);
|
|
||||||
assertThat(consumer.closed()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void whenStartingBySubscribingToTopic_thenExpectUpdatesAreConsumedCorrectly() {
|
|
||||||
// GIVEN
|
|
||||||
consumer.schedulePollTask(() -> {
|
|
||||||
consumer.rebalance(Collections.singletonList(new TopicPartition(TOPIC, PARTITION)));
|
|
||||||
consumer.addRecord(record(TOPIC, PARTITION, "Romania", 20));
|
|
||||||
});
|
|
||||||
consumer.schedulePollTask(() -> countryPopulationConsumer.stop());
|
|
||||||
|
|
||||||
HashMap<TopicPartition, Long> startOffsets = new HashMap<>();
|
|
||||||
TopicPartition tp = new TopicPartition(TOPIC, 0);
|
|
||||||
startOffsets.put(tp, 0L);
|
|
||||||
consumer.updateBeginningOffsets(startOffsets);
|
|
||||||
|
|
||||||
// WHEN
|
|
||||||
countryPopulationConsumer.startBySubscribing(TOPIC);
|
|
||||||
|
|
||||||
// THEN
|
|
||||||
assertThat(updates).hasSize(1);
|
|
||||||
assertThat(consumer.closed()).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
class CountryPopulation {
|
|
||||||
|
|
||||||
private String country;
|
|
||||||
private Integer population;
|
|
||||||
|
|
||||||
// standard constructor, getters and setters
|
|
||||||
|
|
||||||
|
|
||||||
public CountryPopulation(String country, Integer population) {
|
|
||||||
this.country = country;
|
|
||||||
this.population = population;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCountry() {
|
|
||||||
return country;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCountry(String country) {
|
|
||||||
this.country = country;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getPopulation() {
|
|
||||||
return population;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPopulation(Integer population) {
|
|
||||||
this.population = population;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CountryPopulationConsumer {
|
|
||||||
|
|
||||||
private Consumer<String, Integer> consumer;
|
|
||||||
private java.util.function.Consumer<Throwable> exceptionConsumer;
|
|
||||||
private java.util.function.Consumer<CountryPopulation> countryPopulationConsumer;
|
|
||||||
|
|
||||||
// standard constructor
|
|
||||||
|
|
||||||
|
|
||||||
public CountryPopulationConsumer(Consumer<String, Integer> consumer, java.util.function.Consumer<Throwable> exceptionConsumer, java.util.function.Consumer<CountryPopulation> countryPopulationConsumer) {
|
|
||||||
this.consumer = consumer;
|
|
||||||
this.exceptionConsumer = exceptionConsumer;
|
|
||||||
this.countryPopulationConsumer = countryPopulationConsumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void startBySubscribing(String topic) {
|
|
||||||
consume(() -> consumer.subscribe(Collections.singleton(topic)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void startByAssigning(String topic, int partition) {
|
|
||||||
consume(() -> consumer.assign(Collections.singleton(new TopicPartition(topic, partition))));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void consume(Runnable beforePollingTask) {
|
|
||||||
try {
|
|
||||||
beforePollingTask.run();
|
|
||||||
while (true) {
|
|
||||||
ConsumerRecords<String, Integer> records = consumer.poll(Duration.of(10, ChronoUnit.SECONDS));
|
|
||||||
StreamSupport.stream(records.spliterator(), false)
|
|
||||||
.map(record -> new CountryPopulation(record.key(), record.value()))
|
|
||||||
.forEach(countryPopulationConsumer);
|
|
||||||
consumer.commitSync();
|
|
||||||
}
|
|
||||||
} catch (WakeupException e) {
|
|
||||||
System.out.println("Shutting down...");
|
|
||||||
} catch (RuntimeException ex) {
|
|
||||||
exceptionConsumer.accept(ex);
|
|
||||||
} finally {
|
|
||||||
consumer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
consumer.wakeup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConsumerRecord<String, Integer> record(String topic, int partition, String country, int population) {
|
|
||||||
return new ConsumerRecord<>(topic, partition, 0, country, population);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue