package core.framework.impl.kafka;
import core.framework.api.kafka.BulkMessageHandler;
import core.framework.api.kafka.MessageHandler;
import core.framework.api.util.Exceptions;
import core.framework.api.util.Maps;
import core.framework.api.util.Sets;
import core.framework.api.util.Types;
import core.framework.impl.json.JSONReader;
import core.framework.impl.log.LogManager;
import org.apache.kafka.clients.consumer.Consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.Set;
/**
* @author neo
*/
public class KafkaMessageListener {
final Map<String, MessageHandler<?>> handlers = Maps.newHashMap();
final Map<String, BulkMessageHandler<?>> bulkHandlers = Maps.newHashMap();
final Map<String, JSONReader<?>> readers = Maps.newHashMap();
final Kafka kafka;
final LogManager logManager;
private final Logger logger = LoggerFactory.getLogger(KafkaMessageListener.class);
private final String name;
private final Set<String> topics = Sets.newHashSet();
public int poolSize = Runtime.getRuntime().availableProcessors() * 2;
private KafkaMessageListenerThread[] listenerThreads;
KafkaMessageListener(Kafka kafka, String name, LogManager logManager) {
this.kafka = kafka;
this.name = name;
this.logManager = logManager;
}
public <T> void subscribe(String topic, Class<T> messageClass, MessageHandler<T> handler, BulkMessageHandler<T> bulkHandler) {
if (topics.contains(topic)) throw Exceptions.error("topic is already subscribed, topic={}", topic);
topics.add(topic);
if (handler != null) handlers.put(topic, handler);
if (bulkHandler != null) bulkHandlers.put(topic, bulkHandler);
readers.put(topic, JSONReader.of(Types.generic(KafkaMessage.class, messageClass)));
}
public void start() {
listenerThreads = new KafkaMessageListenerThread[poolSize];
String group = logManager.appName == null ? "local" : logManager.appName;
for (int i = 0; i < poolSize; i++) {
String name = "kafka-listener-" + (this.name == null ? "" : this.name + "-") + i;
Consumer<String, byte[]> consumer = kafka.consumer(group, topics);
KafkaMessageListenerThread thread = new KafkaMessageListenerThread(name, consumer, this);
thread.start();
listenerThreads[i] = thread;
}
logger.info("kafka listener started, name={}, uri={}, topics={}", name, kafka.uri, topics);
}
public void stop() {
logger.info("stop kafka listener, name={}, uri={}, topics={}", name, kafka.uri, topics);
for (KafkaMessageListenerThread thread : listenerThreads) {
thread.shutdown();
}
}
}