All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mageddo.kafka.client.DefaultConsumer Maven / Gradle / Ivy

There is a newer version: 1.0.2
Show newest version
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