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

biz.paluch.logging.gelf.intern.sender.KafkaGelfSenderProvider Maven / Gradle / Ivy

The newest version!
package biz.paluch.logging.gelf.intern.sender;

import java.net.URI;
import java.util.Map;
import java.util.Properties;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.ByteArraySerializer;

import biz.paluch.logging.gelf.intern.GelfSender;
import biz.paluch.logging.gelf.intern.GelfSenderConfiguration;
import biz.paluch.logging.gelf.intern.GelfSenderProvider;

/**
 * {@link GelfSenderProvider} providing {@link KafkaGelfSender}.
 *
 * @author Rifat Döver
 * @since 1.13
 */
public class KafkaGelfSenderProvider implements GelfSenderProvider {

    private static final int BROKER_DEFAULT_PORT = 9092;

    @Override
    public boolean supports(String host) {
        return host != null && host.startsWith(KafkaContants.KAFKA_SCHEME + ":");
    }

    @Override
    public GelfSender create(GelfSenderConfiguration configuration) {

        URI uri = URI.create(configuration.getHost());
        Map options = QueryStringParser.parse(uri);

        Properties props = new Properties();
        for (Map.Entry entry : options.entrySet()) {
            props.setProperty(entry.getKey(), entry.getValue());
        }

        String brokers = getBrokerServers(configuration);

        props.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, brokers);

        String kafkaLogTopic = getTopic(uri);

        // Default Configurations
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());

        if (!props.containsKey(ProducerConfig.ACKS_CONFIG)) {
            props.put(ProducerConfig.ACKS_CONFIG, "all");
        } else {
            String acks = props.getProperty(ProducerConfig.ACKS_CONFIG);
            acks = "0".equalsIgnoreCase(acks) ? "1" : acks;
            props.put(ProducerConfig.ACKS_CONFIG, acks);
        }

        if (!props.containsKey(ProducerConfig.RETRIES_CONFIG)) {
            props.put(ProducerConfig.RETRIES_CONFIG, 2);
        }

        KafkaProducer kafkaProducer = new KafkaProducer<>(props);

        return new KafkaGelfSender(kafkaProducer, kafkaLogTopic, configuration.getErrorReporter());
    }

    private static String getBrokerServers(GelfSenderConfiguration configuration) {

        // extract the host part from uri and put in an array
        // so each host can be validated using the URI

        // from https://docs.oracle.com/javase/7/docs/api/java/net/URI.html
        // A hierarchical URI is subject to further parsing according to the syntax
        // [scheme:][//authority][path][?query][#fragment]
        String hconf = configuration.getHost();

        // in order to arrive here, there have to be a kafka scheme
        // get the scheme part
        String scheme = URI.create(hconf).getScheme() + "://";
        // and then begining of host
        String hostsPart = hconf.substring(scheme.length());

        // hostsPart ends with either # or ?
        int pos = findHostPartEnd(hostsPart);

        String suffix = hostsPart.substring(pos);
        hostsPart = hostsPart.substring(0, pos);

        String brokers = "";
        String[] hosts = new String[0];
        if (hostsPart.length() > 0)
            hosts = hostsPart.split(",");
        if (hosts.length > 0)
            for (String host : hosts) {
                String broker;
                String tmp = scheme + host + suffix;
                URI uri = URI.create(tmp);
                if (uri.getHost() != null) {
                    broker = uri.getHost();
                    int port;
                    if (uri.getPort() > 0) {
                        port = uri.getPort();
                    } else if (configuration.getPort() > 0) {
                        port = configuration.getPort();
                    } else {
                        port = BROKER_DEFAULT_PORT;
                    }
                    broker += ":" + port;

                } else {
                    broker = uri.getAuthority();
                }
                if (brokers.length() > 0)
                    brokers += ",";
                brokers += broker;
            }
        if (brokers.isEmpty()) {
            throw new IllegalArgumentException("Kafka URI must specify bootstrap.servers.");
        }

        return brokers;
    }

    private static int findHostPartEnd(String hostsPart) {
        for (int pos = 0; pos < hostsPart.length(); pos++) {
            switch (hostsPart.charAt(pos)) {
                case '#':
                case '?':
                    break;
                default:
                    continue;
            }
            return pos;
        }

        return hostsPart.length();
    }

    private static String getTopic(URI uri) {

        String fragment = uri.getFragment();

        if (fragment == null || fragment.isEmpty()) {
            throw new IllegalArgumentException("Kafka URI must specify log topic as fragment.");
        }

        return fragment;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy