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

com.zaradai.gluon.kafka.AbstractKafkaEventAdaptor Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2017 Zaradai
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zaradai.gluon.kafka; import com.google.common.eventbus.EventBus; import com.google.common.util.concurrent.AbstractExecutionThreadService; import com.zaradai.gluon.codecs.Codec; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.clients.producer.RecordMetadata; import org.apache.kafka.common.TopicPartition; import org.apache.kafka.common.errors.WakeupException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collection; import static com.google.common.base.Preconditions.checkNotNull; abstract class AbstractKafkaEventAdaptor extends AbstractExecutionThreadService { static final String REQUEST_TOPIC = "gluon-req"; static final String REPLY_TOPIC = "gluon-rep"; private static final Logger LOG = LoggerFactory.getLogger(AbstractKafkaEventAdaptor.class); private final EventBus eventBus; private final Codec codec; private final KafkaConfig config; private final KafkaProducer producer; private final KafkaConsumer consumer; AbstractKafkaEventAdaptor(EventBus eventBus, Codec codec, KafkaConfig config, ProducerFactory producerFactory, ConsumerFactory consumerFactory) { checkNotNull(eventBus, "Invalid event bus"); checkNotNull(codec, "Invalid Codec"); checkNotNull(config, "Invalid Kafka config"); checkNotNull(config.getProducerConfig(), "Invalid Kafka producer config"); checkNotNull(config.getConsumerConfig(), "Invalid Kafka consumer config"); checkNotNull(producerFactory, "Invalid producer factory"); checkNotNull(consumerFactory, "Invalid consumer factory"); this.eventBus = eventBus; this.codec = codec; this.config = config; producer = producerFactory.create(config.getProducerConfig()); consumer = consumerFactory.create(config.getConsumerConfig()); } protected abstract Collection getSubscriptionTopics(); protected abstract String getSendTopic(); void handleSendError(Throwable t) { LOG.warn("Error sending message", t); } void handleDecodeError(Throwable t) { LOG.warn("Unable to decode message", t); } @Override protected void startUp() throws Exception { eventBus.register(this); setupConsumer(); } private void setupConsumer() { consumer.subscribe(getSubscriptionTopics()); // try and connect consumer.poll(0); for (TopicPartition topicPartition : consumer.assignment()) { LOG.info("Assigned: {}", topicPartition); } } @Override protected void shutDown() throws Exception { eventBus.unregister(this); producer.close(); } void send(Object msg) { checkNotNull(msg, "Invalid msg"); ProducerRecord record = new ProducerRecord<>(getSendTopic(), codec.encode(msg)); producer.send(record, this::onSent); } void onSent(RecordMetadata recordMetadata, Exception e) { if (e != null) { handleSendError(e); } else { LOG.debug("Sent: {}", recordMetadata); } } @Override protected void run() throws Exception { long poll = config.getConsumerConfig().getPollPeriod(); while (isRunning()) { ConsumerRecords records = read(poll); for (ConsumerRecord record : records) { try { Object received = codec.decode(record.value()); eventBus.post(received); LOG.debug("Published: {}", received); } catch (Throwable t) { handleDecodeError(t); } } } } private ConsumerRecords read(long poll) { ConsumerRecords res = ConsumerRecords.empty(); try { res = consumer.poll(poll); } catch (WakeupException we) { // expected we are being shutdown. } catch (Exception e) { LOG.error("Unable to poll kafka", e); stopAsync(); } return res; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy