Package net.scharrenbach.kafka

Source Code of net.scharrenbach.kafka.KafkaServerRunnable

package net.scharrenbach.kafka;

/*
* #%L
* Kafka Run
* %%
* Copyright (C) 2013 Thomas Scharrenbach
* %%
* 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.server.KafkaConfig;
import kafka.utils.ZkUtils;

import org.I0Itec.zkclient.ZkClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import scala.collection.Iterator;
import scala.collection.Seq;

/**
*
* @author Thomas Scharrenbach
* @version 0.8.0
* @since 0.8.0
*
*/
public class KafkaServerRunnable implements Runnable {

  private static final Logger _log = LoggerFactory
      .getLogger(KafkaServerRunnable.class);

  /**
   * <p>
   * Creates a new runnable with a configuration read from the specified file.
   * </p>
   *
   * @author Thomas Scharrenbach
   * @version 0.8.0
   * @since 0.8.0
   *
   * @param kafkaConfig
   * @param addShutdownHook
   * @return
   */
  public static final KafkaServerRunnable newInstance(String kafkaConfigFile,
      boolean addShutdownHook) {

    // Parse the config from file.
    final KafkaConfig kafkaConfig = new KafkaConfig(
        kafka.utils.Utils.loadProps(kafkaConfigFile));

    return newInstance(kafkaConfig, addShutdownHook);
  }

  /**
   * <p>
   * Creates a new runnable with the specified configuration.
   * </p>
   *
   * @author Thomas Scharrenbach
   * @version 0.8.0
   * @since 0.8.0
   *
   * @param kafkaConfig
   * @param addShutdownHook
   * @return
   */
  public static final KafkaServerRunnable newInstance(
      KafkaConfig kafkaConfig, boolean addShutdownHook) {
    // Create the actual server.
    final kafka.server.KafkaServerStartable kafkaServer = new kafka.server.KafkaServerStartable(
        kafkaConfig);

    final KafkaServerRunnable runnable = new KafkaServerRunnable(
        kafkaServer, kafkaConfig);
    // Add shutdown hook if desired.
    if (addShutdownHook) {
      addShutdownHook(runnable);
    }
    return runnable;
  }

  /**
   * Adds a shutdown hook that shuts down the Kafka server.
   *
   * @author Thomas Scharrenbach
   * @version 0.8.0
   * @since 0.8.0
   *
   * @param kafkaServer
   */
  private static final void addShutdownHook(
      final KafkaServerRunnable kafkaServerRunnable) {
    kafkaServerRunnable.shutdown();
  }

  //
  // Fields
  //

  private final kafka.server.KafkaServerStartable _kafkaServer;
  private final KafkaConfig _kafkaConfig;
  private boolean _kafkaServerStarted;

  //
  // Constructors
  //

  /**
   * Simple copy constructor.
   *
   * @author Thomas Scharrenbach
   * @version 0.8.0
   * @since 0.8.0
   *
   * @param kafkaServer
   * @param kafkaConfig
   */
  private KafkaServerRunnable(kafka.server.KafkaServerStartable kafkaServer,
      KafkaConfig kafkaConfig) {
    _kafkaServer = kafkaServer;
    _kafkaConfig = kafkaConfig;
  }

  /**
   * Starts the Kafka server.
   *
   * @author Thomas Scharrenbach
   * @version 0.8.0
   * @since 0.8.0
   */
  public void run() {
    _log.info("Started starting Kafka...");
    try {
      _kafkaServer.startup();
      Thread.sleep(10);
      _kafkaServerStarted = true;
    } catch (Exception e) {
      _log.error("Error starting Kafka!", e);
      throw new RuntimeException(e);
    }
    _log.info("Finished starting Kafka.");
  }

  /**
   * Add a new topic to the running Kafka server.
   *
   * @param topic
   *            the topic to add.
   * @throws IllegalStateException
   *             if Kafka server has not yet been started.
   *
   * @author Thomas Scharrenbach
   * @version 0.8.0
   * @since 0.8.0
   *
   */
  public void addTopic(KafkaTopicBean topic) {
    int waitForStartedCounter = 0;
    int maxTriesStarted = 5;
    while (waitForStartedCounter < maxTriesStarted && !_kafkaServerStarted) {
      ++waitForStartedCounter;
      _log.debug("Waiting for Kafka server to be started round "
          + waitForStartedCounter + " of " + maxTriesStarted);
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
      }
    }
    if (!_kafkaServerStarted) {
      throw new IllegalStateException(String.format(
          "Kafka server not started!" + " Could not add topic %s!",
          topic));
    }
    try {

      _log.debug("Checking whether topic is already defined...");
      String zkConnect = _kafkaConfig.zkConnect();
      final ZkClient zkClient = new ZkClient(zkConnect, 30000, 30000,
          kafka.utils.ZKStringSerializer$.MODULE$);

      final Seq<String> topicList = ZkUtils.getChildrenParentMayNotExist(
          zkClient, ZkUtils.BrokerTopicsPath());

      boolean topicExists = false;
      final Iterator<String> topicListIt = topicList.iterator();
      final String topicName = topic.getTopic();
      while (topicListIt.hasNext() && !topicExists) {
        final String existingTopic = topicListIt.next();
        _log.debug("Checking existing topic {} with new topic {}",
            existingTopic, topicName);
        if (topicName.equals(existingTopic)) {
          topicExists = true;
          _log.info("Topic {} already exists doing nothing...", topicName);
        }
      }
      if (!topicExists) {
        _log.info("Topic {} does not yet exist, creating it...", topicName);
        _log.info("Started starting Kafka topic {}...", topicName);
        kafka.admin.CreateTopicCommand.createTopic(zkClient,
            topic.getTopic(), topic.getNPartitions(),
            topic.getReplicationFactor(),
            topic.getReplicaAssignmentStr());
        Thread.sleep(10);
        _log.info("Finished starting Kafka topic {}.", topicName);
      }
    } catch (Exception e) {
      _log.error("Error starting Kafka topic {}!", topic);
      throw new RuntimeException(e);
    }

  }

  /**
   *
   */
  public void shutdown() {
    try {
      Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
          _log.info("Started stopping Kafka...");
          _kafkaServer.shutdown();
          _log.info("Finished stopping Kafka.");
        }
      });

    } catch (Exception e) {
      _log.error("Error stopping Kafka!", e);
      assert false;
    }

  }

}
TOP

Related Classes of net.scharrenbach.kafka.KafkaServerRunnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.