com.mageddo.kafka.client.DefaultConsumer Maven / Gradle / Ivy
package com.mageddo.kafka.client;
import java.time.Duration;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.OffsetAndMetadata;
import org.apache.kafka.common.TopicPartition;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class DefaultConsumer implements ThreadConsumer, AutoCloseable {
private AtomicBoolean started = new AtomicBoolean();
private ExecutorService executor;
protected abstract void consume(ConsumerRecords records);
protected abstract Consumer consumer();
protected abstract Consumers consumerConfig();
@Override
public void start() {
if(started.get()){
log.warn("status=already-started");
return ;
}
final Consumer consumer = consumer();
this.executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
log.info("status=consumer-starting");
consumer.subscribe(consumerConfig().topics());
this.poll(consumer, consumerConfig());
});
started.set(true);
}
public void poll(Consumer consumer, ConsumingConfig consumingConfig) {
if (consumingConfig.batchCallback() == null && consumingConfig.callback() == null) {
throw new IllegalArgumentException("You should inform BatchCallback Or Callback");
}
while (!Thread.currentThread().isInterrupted()) {
final ConsumerRecords records = consumer.poll(consumingConfig.pollTimeout());
if (log.isTraceEnabled()) {
log.trace("status=polled, records={}", records.count());
}
this.consume(records);
if(!Duration.ZERO.equals(consumingConfig.pollInterval())){
this.sleep(consumingConfig.pollInterval());
}
}
}
/**
* Sleep for some duration
*/
protected void sleep(Duration timeout) {
try {
TimeUnit.MILLISECONDS.sleep(timeout.toMillis());
} catch (InterruptedException e) {
Thread
.currentThread()
.interrupt();
}
}
void commitSyncRecord(Consumer consumer, ConsumerRecord record) {
consumer.commitSync(Collections.singletonMap(
new TopicPartition(record.topic(), record.partition()),
new OffsetAndMetadata(record.offset())
));
}
void doRecoverWhenAvailable(RecoverContext ctx, RecoverCallback recoverCallback) {
if (recoverCallback != null) {
recoverCallback.recover(ctx);
commitSyncRecord(ctx.consumer(), ctx.record());
} else {
log.warn("status=no recover callback was specified");
}
}
@Override
public void close() {
this.executor.shutdownNow();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy