package com.neverwinterdp.zk.tool.server; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.apache.zookeeper.server.DatadirCleanupManager; import org.apache.zookeeper.server.ServerConfig; import org.apache.zookeeper.server.ZooKeeperServerMain; import org.apache.zookeeper.server.quorum.QuorumPeerConfig; import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException; import org.apache.zookeeper.server.quorum.QuorumPeerMain; import com.neverwinterdp.tool.server.Server; import com.neverwinterdp.util.JSONSerializer; /** * @author Tuan Nguyen * @email tuan08@gmail.com */ public class EmbededZKServer implements Server { private ZookeeperLaucher launcher; private Thread zkThread; private Properties zkProperties = new Properties(); private int port; public EmbededZKServer(Map<String, String> overrideProperties) { init(overrideProperties); } public EmbededZKServer(String dataDir, int port) { Map<String, String> props = new HashMap<String, String>(); props.put("dataDir", dataDir); this.port = port; props.put("clientPort", Integer.toString(port)); init(props); } public EmbededZKServer(String dataDir) { this(dataDir, 2181); } void init(Map<String, String> overrideProperties) { zkProperties.put("dataDir", "./build/data/zookeeper"); // the port at which the clients will connect zkProperties.put("clientPort", "2181"); if (overrideProperties != null) { zkProperties.putAll(overrideProperties); } //disable the per-ip limit on the number of connections since this is a non-production config zkProperties.put("maxClientCnxns", "60"); } public void start() throws Exception { if (launcher != null) { throw new IllegalStateException("ZookeeperLaucher should be null"); } System.out.println("zookeeper config zkProperties: \n" + JSONSerializer.INSTANCE.toString(zkProperties)); zkThread = new Thread() { public void run() { try { launcher = create(zkProperties); launcher.start(); } catch (Exception ex) { launcher = null; System.err.println("Cannot lauch the EmbededZKServer" + ex); throw new RuntimeException("Cannot lauch the EmbededZKServer", ex); } } }; zkThread.start(); // wait to make sure the server is launched Thread.sleep(3000); } ZookeeperLaucher create(Properties zkProperties) throws ConfigException, IOException { QuorumPeerConfig zkConfig = new QuorumPeerConfig(); zkConfig.parseProperties(zkProperties); DatadirCleanupManager purgeMgr = new DatadirCleanupManager(zkConfig.getDataDir(), zkConfig.getDataLogDir(), zkConfig.getSnapRetainCount(), zkConfig.getPurgeInterval()); purgeMgr.start(); if (zkConfig.getServers().size() > 0) { return new QuorumPeerMainExt(zkConfig); } else { System.out .println("Either no config or no quorum defined in config, running in standalone mode"); // there is only server in the quorum -- run as standalone return new ZooKeeperServerMainExt(zkConfig); } } @Override public String getHost() { return "127.0.0.1"; } @Override public int getPort() { return this.port; } @Override public String getConnectString() { return getHost() + ":" + getPort() ; } @Override public void shutdown() { if (launcher != null) { launcher.shutdown(); launcher = null; } } static public interface ZookeeperLaucher { void start() throws Exception; void shutdown(); QuorumPeerConfig getConfig(); } public class QuorumPeerMainExt extends QuorumPeerMain implements ZookeeperLaucher { private QuorumPeerConfig zkConfig; public QuorumPeerMainExt(QuorumPeerConfig zkConfig) { this.zkConfig = zkConfig; } public void start() throws Exception { runFromConfig(zkConfig); } public void shutdown() { quorumPeer.shutdown(); } @Override public QuorumPeerConfig getConfig() { return zkConfig; } } public class ZooKeeperServerMainExt extends ZooKeeperServerMain implements ZookeeperLaucher { private QuorumPeerConfig qConfig; public ZooKeeperServerMainExt(QuorumPeerConfig qConfig) { this.qConfig = qConfig; } public void start() throws Exception { ServerConfig config = new ServerConfig(); config.readFrom(qConfig); // ManagedUtil.registerLog4jMBeans(); runFromConfig(config); } public void shutdown() { super.shutdown(); } @Override public QuorumPeerConfig getConfig() { return qConfig; } } }