package com.devicehive.test.rule; /* * #%L * DeviceHive Test Utils * %% * 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 kafka.admin.AdminUtils; import kafka.server.KafkaConfig; import kafka.server.KafkaServer; import kafka.server.NotRunning; import kafka.utils.*; import org.I0Itec.zkclient.ZkClient; import org.I0Itec.zkclient.exception.ZkInterruptedException; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.common.protocol.SecurityProtocol; import org.apache.kafka.common.utils.Utils; import org.apache.zookeeper.server.NIOServerCnxnFactory; import org.apache.zookeeper.server.ZooKeeperServer; import org.junit.rules.ExternalResource; import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Optional; import java.util.Properties; public class KafkaEmbeddedRule extends ExternalResource { private static final int KAFKA_DEFAULT_PORT = 9092; private static final int ZOOKEEPER_DEFAULT_PORT = 2181; private boolean controlledShutdown; private int partitions; private String[] topics; private String zkConnect; private EmbeddedZookeeperInternal zookeeper; private ZkClient zookeeperClient; private KafkaServer kafkaServer; public KafkaEmbeddedRule(boolean controlledShutdown, int partitions, String... topics) { this.controlledShutdown = controlledShutdown; this.partitions = partitions; this.topics = topics; } static class EmbeddedZookeeperInternal { private final ZooKeeperServer zooKeeperServer; private final NIOServerCnxnFactory nioServerCnxnFactory; private final java.io.File logDir; private final java.io.File snapshotDir; private final int port; public EmbeddedZookeeperInternal(int port) throws IOException, InterruptedException { this.port = port; logDir = TestUtils.tempDir(); snapshotDir = TestUtils.tempDir(); zooKeeperServer = new ZooKeeperServer(snapshotDir, logDir, 500); nioServerCnxnFactory = new NIOServerCnxnFactory(); InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", port); nioServerCnxnFactory.configure(inetSocketAddress, 0); nioServerCnxnFactory.startup(zooKeeperServer); } public void shutdown() { zooKeeperServer.shutdown(); nioServerCnxnFactory.shutdown(); Utils.delete(logDir); Utils.delete(snapshotDir); } public int getPort() { return port; } } @Override protected void before() throws Throwable { int zkConnectionTimeout = 6000; int zkSessionTimeout = 6000; int zookeeperPort = Optional.ofNullable(System.getProperty("zookeeper.port")) .filter(s -> !s.isEmpty()) .map(Integer::parseInt) .orElse(ZOOKEEPER_DEFAULT_PORT); this.zookeeper = new EmbeddedZookeeperInternal(zookeeperPort); this.zkConnect = "127.0.0.1:" + this.zookeeper.getPort(); this.zookeeperClient = new ZkClient(this.zkConnect, zkSessionTimeout, zkConnectionTimeout, ZKStringSerializer$.MODULE$); int kafkaPort = Optional.ofNullable(System.getProperty("kafka.port")) .filter(s -> !s.isEmpty()) .map(Integer::parseInt) .orElse(KAFKA_DEFAULT_PORT); Properties brokerConfigProperties = TestUtils.createBrokerConfig(0, this.zkConnect, this.controlledShutdown, true, kafkaPort, scala.Option.<SecurityProtocol>apply(null), scala.Option.<File>apply(null), scala.Option.<Properties>apply(null), true, false, 0, false, 0, false, 0, scala.Option.<String>apply(null)); brokerConfigProperties.setProperty("replica.socket.timeout.ms", "1000"); brokerConfigProperties.setProperty("controller.socket.timeout.ms", "1000"); brokerConfigProperties.setProperty("offsets.topic.replication.factor", "1"); this.kafkaServer = TestUtils.createServer(new KafkaConfig(brokerConfigProperties), SystemTime$.MODULE$); ZkUtils zkUtils = new ZkUtils(this.zookeeperClient, null, false); Properties properties = new Properties(); for (String topic : this.topics) { if (!AdminUtils.topicExists(zkUtils, topic)) { AdminUtils.createTopic(zkUtils, topic, partitions, 1, properties, null); } } } @Override protected void after() { try { if (this.kafkaServer.brokerState().currentState() != (NotRunning.state())) { this.kafkaServer.shutdown(); this.kafkaServer.awaitShutdown(); } } catch (Exception e) { } try { CoreUtils.delete(this.kafkaServer.config().logDirs()); } catch (Exception e) { } try { this.zookeeperClient.close(); } catch (ZkInterruptedException e) { } try { this.zookeeper.shutdown(); } catch (Exception e) { } } public String getZkConnect() { return this.zkConnect; } public String getBrokerAddress() { return "localhost:" + kafkaServer.config().port(); } public Properties getProducerProperties() { Properties producerProps = new Properties(); producerProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, getBrokerAddress()); producerProps.put(ProducerConfig.ACKS_CONFIG, "all"); return producerProps; } public Properties getConsumerProperties() { Properties consumerProps = new Properties(); consumerProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, getBrokerAddress()); consumerProps.put(ConsumerConfig.GROUP_ID_CONFIG, "request-group"); consumerProps.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000"); return consumerProps; } }