com.devicehive.shim.config.server.KafkaRpcServerConfig.java Source code

Java tutorial

Introduction

Here is the source code for com.devicehive.shim.config.server.KafkaRpcServerConfig.java

Source

package com.devicehive.shim.config.server;

/*
 * #%L
 * DeviceHive Shim Kafka Implementation
 * %%
 * Copyright (C) 2016 DataArt
 * %%
 * 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.
 * #L%
 */

import com.devicehive.shim.api.Response;
import com.devicehive.shim.api.server.RequestHandler;
import com.devicehive.shim.api.server.RpcServer;
import com.devicehive.shim.kafka.server.KafkaRpcServer;
import com.devicehive.shim.kafka.server.RequestConsumer;
import com.devicehive.shim.kafka.server.ServerEvent;
import com.devicehive.shim.kafka.server.ServerEventHandler;
import com.devicehive.shim.kafka.serializer.RequestSerializer;
import com.devicehive.shim.kafka.serializer.ResponseSerializer;
import com.google.gson.Gson;
import com.lmax.disruptor.*;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Configuration
@Profile("rpc-server")
@PropertySource("classpath:kafka.properties")
public class KafkaRpcServerConfig {

    public static final String REQUEST_TOPIC = "request_topic";

    @Autowired
    private Environment env;

    @Value("${rpc.server.request-consumer.group}")
    private String requestConsumerGroup;

    @Value("${rpc.server.request-consumer.threads:1}")
    private int consumerThreads;

    @Value("${rpc.server.worker.threads:1}")
    private int workerThreads;

    @Value("${lmax.buffer-size:1024}")
    private int bufferSize;

    @Value("${rpc.server.disruptor.wait-strategy}")
    private String waitStrategyType;

    @Bean(name = "server-producer")
    public Producer<String, Response> kafkaResponseProducer(Gson gson) {
        return new KafkaProducer<>(producerProps(), new StringSerializer(), new ResponseSerializer(gson));
    }

    @Bean
    public ExecutorService workerExecutor() {
        return Executors.newFixedThreadPool(workerThreads);
    }

    @Bean
    public WaitStrategy disruptorWaitStrategy() {
        WaitStrategy strategy;
        switch (waitStrategyType) {
        case "sleeping":
            strategy = new SleepingWaitStrategy();
            break;
        case "yielding":
            strategy = new YieldingWaitStrategy();
            break;
        case "busy-spin":
            strategy = new BusySpinWaitStrategy();
            break;
        case "blocking":
        default:
            strategy = new BlockingWaitStrategy();
        }
        return strategy;
    }

    @Bean
    public Disruptor<ServerEvent> disruptor(@Qualifier("workerExecutor") ExecutorService workerExecutor,
            WaitStrategy waitStrategy) {
        ProducerType producerType = ProducerType.SINGLE;
        if (consumerThreads > 1) {
            producerType = ProducerType.MULTI;
        }

        return new Disruptor<>(ServerEvent::new, bufferSize, workerExecutor, producerType, waitStrategy);
    }

    @Bean
    public ServerEventHandler serverEventHandler(RequestHandler requestHandler,
            @Qualifier("server-producer") Producer<String, Response> responseProducer) {
        return new ServerEventHandler(requestHandler, responseProducer);
    }

    @Bean
    public RequestConsumer requestConsumer(Gson gson) {
        return new RequestConsumer(REQUEST_TOPIC, consumerProps(), consumerThreads, new RequestSerializer(gson));
    }

    @Bean
    public RpcServer rpcServer(Disruptor<ServerEvent> disruptor, RequestConsumer requestConsumer,
            ServerEventHandler eventHandler) {
        RpcServer server = new KafkaRpcServer(disruptor, requestConsumer, eventHandler);
        server.start();
        return server;
    }

    private Properties producerProps() {
        Properties props = new Properties();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, env.getProperty("bootstrap.servers"));
        return props;
    }

    private Properties consumerProps() {
        Properties props = new Properties();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, env.getProperty("bootstrap.servers"));
        props.put(ConsumerConfig.GROUP_ID_CONFIG, requestConsumerGroup);
        props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,
                env.getProperty(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG));
        return props;
    }

}