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

io.soffa.foundation.pubsub.kafka.KafkaClient.jav_ Maven / Gradle / Ivy

package io.soffa.foundation.pubsub.kafka;

import io.soffa.foundation.commons.Logger;
import io.soffa.foundation.commons.ObjectUtil;
import io.soffa.foundation.model.Message;
import io.soffa.foundation.model.OperationResult;
import io.soffa.foundation.pubsub.AbstractPubSubClient;
import io.soffa.foundation.pubsub.MessageHandler;
import io.soffa.foundation.pubsub.PubSubClient;
import io.soffa.foundation.pubsub.config.PubSubClientConfig;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.*;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.kafka.listener.KafkaMessageListenerContainer;
import org.springframework.kafka.listener.MessageListener;
import org.springframework.kafka.requestreply.ReplyingKafkaTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import static org.springframework.kafka.support.KafkaHeaders.GROUP_ID;

public class KafkaClient extends AbstractPubSubClient implements PubSubClient {

    private static final Logger LOG = Logger.get(KafkaClient.class);
    private final PubSubClientConfig config;
    private KafkaTemplate kafkaTemplate;
    private ConsumerFactory consumerFactory;
    private ReplyingKafkaTemplate replyingKafkaTemplate;

    public KafkaClient(PubSubClientConfig config, String broadcasting) {
        super(config, broadcasting);
        this.config = config;
        configure();
    }

    public void configure() {
        configurePublisher();
        configureConsumer();
    }

    private void configurePublisher() {
        Map configurations = new HashMap<>();
        configurations.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, config.getAddresses());
        configurations.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        configurations.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        ProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(configurations);
        kafkaTemplate = new KafkaTemplate<>(producerFactory);

        ConsumerFactory consumerFactory = new DefaultKafkaConsumerFactory<>(configurations);

        ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory);
        factory.setReplyTemplate(kafkaTemplate);

        ContainerProperties containerProperties = new ContainerProperties(subject);

        KafkaMessageListenerContainer mlc = new KafkaMessageListenerContainer(consumerFactory, configurations);

        replyingKafkaTemplate = new ReplyingKafkaTemplate(producerFactory, consumerFactory);
    }

    private void configureConsumer() {
        Map configurations = new HashMap<>();
        configurations.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, config.getAddresses());
        configurations.put(ConsumerConfig.GROUP_ID_CONFIG, GROUP_ID);
        configurations.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        configurations.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        consumerFactory = new DefaultKafkaConsumerFactory<>(configurations);
    }

    @Override
    public void subscribe(@NonNull String subject, boolean broadcast, MessageHandler handler) {
        ContainerProperties containerProperties = new ContainerProperties(subject);
        containerProperties.setMessageListener(new MessageListener(){
            @Override
            public void onMessage(@NonNull ConsumerRecord record) {
                io.soffa.foundation.model.Message message = ObjectUtil.deserialize(record.value(), io.soffa.foundation.model.Message.class);
                OperationResult response = OperationResult.create(handler.handle(message).orElse(null), null);

            }
        });
        ConcurrentMessageListenerContainer container = new ConcurrentMessageListenerContainer<>(consumerFactory, containerProperties);
        container.start();
    }

    @Override
    public void publish(@NonNull String subject, Message message) {
        kafkaTemplate.send(subject, ObjectUtil.serialize(message));
    }

    @Override
    public void broadcast(@NonNull String target, Message message) {
        String sub = resolveBroadcast(target);
        kafkaTemplate.send(sub, ObjectUtil.serialize(message));
    }

    @Override
    public CompletableFuture internalRequest(@NonNull String subject, Message message) {
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy