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

com.epam.eco.commons.kafka.cache.KafkaCache Maven / Gradle / Ivy

Go to download

A library of utilities, helpers and higher-level APIs for the Kafka client library

There is a newer version: 3.0.5
Show newest version
/*
 * Copyright 2019 EPAM Systems
 *
 * 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.epam.eco.commons.kafka.cache;

import java.util.Map;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.epam.eco.commons.kafka.KafkaUtils;
import com.epam.eco.commons.kafka.config.ConsumerConfigBuilder;
import com.epam.eco.commons.kafka.config.ProducerConfigBuilder;
import com.epam.eco.commons.kafka.config.TopicConfigBuilder;
import com.epam.eco.commons.kafka.consumer.bootstrap.OffsetInitializer;
import com.epam.eco.commons.kafka.serde.KeyValueDecoder;

/**
 * @author Andrei_Tytsik
 */
public class KafkaCache extends AbstractCache {

    private final static Logger LOGGER = LoggerFactory.getLogger(KafkaCache.class);

    private final CacheTopic topic;
    private final MapCacheConsumer consumer;
    private final CacheProducer producer;

    private KafkaCache(
            String bootstrapServers,
            String topicName,
            int topicPartitionCount,
            int topicReplicationFactor,
            Map topicConfig,
            long bootstrapTimeoutInMs,
            Map consumerConfig,
            OffsetInitializer offsetInitializer,
            KeyValueDecoder keyValueDecoder,
            int consumerParallelism,
            boolean readOnly,
            Map producerConfig,
            boolean storeData,
            FireUpdateMode fireUpdateMode,
            CacheListener listener) {
        super(storeData, fireUpdateMode, listener);

        Validate.notBlank(bootstrapServers, "Bootstrap servers list is blank");
        Validate.notBlank(topicName, "Topic name is blank");

        topic = new CacheTopic(
                bootstrapServers,
                topicName,
                topicPartitionCount,
                topicReplicationFactor,
                topicConfig,
                consumerConfig);

        consumer = new MapCacheConsumer<>(
                topicName,
                bootstrapServers,
                bootstrapTimeoutInMs,
                consumerConfig,
                offsetInitializer,
                keyValueDecoder,
                consumerParallelism,
                this::applyUpdateFromUnderlying);

        producer =
                !readOnly ?
                new CacheProducer<>(topicName, bootstrapServers, producerConfig) :
                null;

        LOGGER.info("Initialized");
    }

    private boolean isReadOnly() {
        return producer == null;
    }

    @Override
    public void start() throws Exception {
        if (!isReadOnly()) {
            topic.createIfNotExists();
        }
        consumer.start();

        LOGGER.info("Started");
    }

    @Override
    protected void applyUpdateToUnderlying(Map update) {
        if (producer == null) {
            return;
        }

        producer.send(update);
    }

    @Override
    public void close() {
        KafkaUtils.closeQuietly(producer);
        KafkaUtils.closeQuietly(consumer);

        LOGGER.info("Closed");
    }

    public static  Builder builder() {
        return new Builder<>();
    }

    public static class Builder {

        private String bootstrapServers;
        private String topicName;
        private int topicPartitionCount = -1;
        private int topicReplicationFactor = -1;
        private Map topicConfig;
        private TopicConfigBuilder topicConfigBuilder;
        private long bootstrapTimeoutInMs = 30000;
        private Map consumerConfig;
        private ConsumerConfigBuilder consumerConfigBuilder;
        private OffsetInitializer offsetInitializer;
        private KeyValueDecoder keyValueDecoder;
        private int consumerParallelism = 1;
        private boolean readOnly = true;
        private Map producerConfig;
        private ProducerConfigBuilder producerConfigBuilder;
        private boolean storeData = true;
        private FireUpdateMode fireUpdateMode = FireUpdateMode.EFFECTIVE;
        private CacheListener listener;

        public Builder bootstrapServers(String bootstrapServers) {
            this.bootstrapServers = bootstrapServers;
            return this;
        }
        public Builder topicName(String topicName) {
            this.topicName = topicName;
            return this;
        }
        public Builder topicPartitionCount(int topicPartitionCount) {
            this.topicPartitionCount = topicPartitionCount;
            return this;
        }
        public Builder topicReplicationFactor(int topicReplicationFactor) {
            this.topicReplicationFactor = topicReplicationFactor;
            return this;
        }
        public Builder topicConfig(Map topicConfig) {
            this.topicConfig = consumerConfig;
            return this;
        }
        public Builder topicConfigBuilder(TopicConfigBuilder topicConfigBuilder) {
            this.topicConfigBuilder = topicConfigBuilder;
            return this;
        }
        public Builder bootstrapTimeoutInMs(long bootstrapTimeoutInMs) {
            this.bootstrapTimeoutInMs = bootstrapTimeoutInMs;
            return this;
        }
        public Builder consumerConfig(Map consumerConfig) {
            this.consumerConfig = consumerConfig;
            return this;
        }
        public Builder consumerConfigBuilder(ConsumerConfigBuilder consumerConfigBuilder) {
            this.consumerConfigBuilder = consumerConfigBuilder;
            return this;
        }
        public Builder offsetInitializer(OffsetInitializer offsetInitializer) {
            this.offsetInitializer = offsetInitializer;
            return this;
        }
        public Builder keyValueDecoder(KeyValueDecoder keyValueDecoder) {
            this.keyValueDecoder = keyValueDecoder;
            return this;
        }
        public Builder consumerParallelism(int consumerParallelism) {
            this.consumerParallelism = consumerParallelism;
            return this;
        }
        public Builder consumerParallelismAvailableCores() {
            this.consumerParallelism = Runtime.getRuntime().availableProcessors();
            return this;
        }
        public Builder readOnly(boolean readOnly) {
            this.readOnly = readOnly;
            return this;
        }
        public Builder producerConfig(Map producerConfig) {
            this.producerConfig = producerConfig;
            return this;
        }
        public Builder producerConfigBuilder(ProducerConfigBuilder producerConfigBuilder) {
            this.producerConfigBuilder = producerConfigBuilder;
            return this;
        }
        public Builder storeData(boolean storeData) {
            this.storeData = storeData;
            return this;
        }
        public Builder fireUpdateModeEffective() {
            return fireUpdateMode(FireUpdateMode.EFFECTIVE);
        }
        public Builder fireUpdateModeAll() {
            return fireUpdateMode(FireUpdateMode.ALL);
        }
        public Builder fireUpdateMode(FireUpdateMode fireUpdateMode) {
            this.fireUpdateMode = fireUpdateMode;
            return this;
        }
        public Builder listener(CacheListener listener) {
            this.listener = listener;
            return this;
        }

        public KafkaCache build() {
            return new KafkaCache<>(
                    bootstrapServers,
                    topicName,
                    topicPartitionCount,
                    topicReplicationFactor,
                    topicConfigBuilder != null ? topicConfigBuilder.build() : topicConfig,
                    bootstrapTimeoutInMs,
                    consumerConfigBuilder != null ? consumerConfigBuilder.build() : consumerConfig,
                    offsetInitializer,
                    keyValueDecoder,
                    consumerParallelism,
                    readOnly,
                    producerConfigBuilder != null ? producerConfigBuilder.build() : producerConfig,
                    storeData,
                    fireUpdateMode,
                    listener);
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy