From b5a5999e545b36dbdb6565d30c424081fa7e00e9 Mon Sep 17 00:00:00 2001 From: Harald Musum Date: Sun, 27 Oct 2019 10:21:04 +0100 Subject: Revert "Revert "Reapply "Create seperate bundles compiled against different ZooKeeper versions""" --- clustercontroller-apps/pom.xml | 2 +- configserver/pom.xml | 2 +- parent/pom.xml | 11 +- .../vespa-standalone-container.spec | 8 +- zkfacade/pom.xml | 3 +- zookeeper-command-line-client/pom.xml | 1 + zookeeper-server/CMakeLists.txt | 4 +- zookeeper-server/pom.xml | 40 +----- .../vespa/zookeeper/VespaZooKeeperServer.java | 11 -- .../vespa/zookeeper/VespaZooKeeperServerImpl.java | 133 ------------------- .../com/yahoo/vespa/zookeeper/package-info.java | 5 - .../zookeeper/VespaZooKeeperServerImplTest.java | 140 -------------------- .../zookeeper-server-3.4/CMakeLists.txt | 2 + zookeeper-server/zookeeper-server-3.4/pom.xml | 69 ++++++++++ .../vespa/zookeeper/VespaZooKeeperServerImpl.java | 133 +++++++++++++++++++ .../zookeeper/VespaZooKeeperServerImplTest.java | 140 ++++++++++++++++++++ .../zookeeper-server-3.5/CMakeLists.txt | 2 + zookeeper-server/zookeeper-server-3.5/pom.xml | 69 ++++++++++ .../vespa/zookeeper/VespaZooKeeperServerImpl.java | 135 +++++++++++++++++++ .../zookeeper/VespaZooKeeperServerImplTest.java | 144 +++++++++++++++++++++ .../zookeeper-server-common/CMakeLists.txt | 2 + zookeeper-server/zookeeper-server-common/pom.xml | 52 ++++++++ .../vespa/zookeeper/VespaZooKeeperServer.java | 11 ++ .../com/yahoo/vespa/zookeeper/package-info.java | 5 + 24 files changed, 786 insertions(+), 338 deletions(-) delete mode 100644 zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java delete mode 100644 zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java delete mode 100644 zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/package-info.java delete mode 100644 zookeeper-server/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java create mode 100644 zookeeper-server/zookeeper-server-3.4/CMakeLists.txt create mode 100644 zookeeper-server/zookeeper-server-3.4/pom.xml create mode 100644 zookeeper-server/zookeeper-server-3.4/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java create mode 100644 zookeeper-server/zookeeper-server-3.4/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java create mode 100644 zookeeper-server/zookeeper-server-3.5/CMakeLists.txt create mode 100644 zookeeper-server/zookeeper-server-3.5/pom.xml create mode 100644 zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java create mode 100644 zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java create mode 100644 zookeeper-server/zookeeper-server-common/CMakeLists.txt create mode 100644 zookeeper-server/zookeeper-server-common/pom.xml create mode 100644 zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java create mode 100644 zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/package-info.java diff --git a/clustercontroller-apps/pom.xml b/clustercontroller-apps/pom.xml index 8d8255493bf..38f10dd74b6 100644 --- a/clustercontroller-apps/pom.xml +++ b/clustercontroller-apps/pom.xml @@ -55,7 +55,7 @@ com.yahoo.vespa - zookeeper-server + zookeeper-server-common ${project.version} provided diff --git a/configserver/pom.xml b/configserver/pom.xml index de7fe02452f..b39686c31d9 100644 --- a/configserver/pom.xml +++ b/configserver/pom.xml @@ -192,7 +192,7 @@ com.yahoo.vespa - zookeeper-server + zookeeper-server-common ${project.version} provided diff --git a/parent/pom.xml b/parent/pom.xml index 56158086fae..e7cb674822e 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -650,15 +650,6 @@ velocity 1.7 - - - org.apache.zookeeper - zookeeper - ${zookeeper.version} - org.assertj assertj-core @@ -788,7 +779,7 @@ 3.7.0 2.22.0 1.12.0 - 3.4.14 + 3.4.14 all true diff --git a/standalone-container/vespa-standalone-container.spec b/standalone-container/vespa-standalone-container.spec index c8029a81bf6..0dc4c54a409 100644 --- a/standalone-container/vespa-standalone-container.spec +++ b/standalone-container/vespa-standalone-container.spec @@ -62,7 +62,6 @@ declare -a modules=( vespa-athenz vespaclient-container-plugin zkfacade - zookeeper-server ) for module in "${modules[@]}"; do cp "$module"/target/"$module"-jar-with-dependencies.jar "$jars_dir" @@ -71,6 +70,13 @@ done # vespajlib must be installed _without_ dependencies. cp vespajlib/target/vespajlib.jar "$jars_dir" +# Copy from submodules, so must be done separately +cp zookeeper-server/zookeeper-server-common/target/zookeeper-server-common-jar-with-dependencies.jar "$jars_dir" +cp zookeeper-server/zookeeper-server-3.4/target/zookeeper-server-3.4-jar-with-dependencies.jar "$jars_dir" +cp zookeeper-server/zookeeper-server-3.5/target/zookeeper-server-3.5-jar-with-dependencies.jar "$jars_dir" +# Symlink to default version +ln -s zookeeper-server-3.4-jar-with-dependencies.jar "$jars_dir"/zookeeper-server-jar-with-dependencies.jar + declare -a libexec_files=( standalone-container/src/main/sh/standalone-container.sh security-tools/src/main/sh/vespa-curl-wrapper diff --git a/zkfacade/pom.xml b/zkfacade/pom.xml index e32a86937e8..b857c31d262 100644 --- a/zkfacade/pom.xml +++ b/zkfacade/pom.xml @@ -37,7 +37,7 @@ com.yahoo.vespa - zookeeper-server + zookeeper-server-common ${project.version} provided @@ -80,6 +80,7 @@ org.apache.zookeeper zookeeper + ${zookeeper.client.version} diff --git a/zookeeper-command-line-client/pom.xml b/zookeeper-command-line-client/pom.xml index f4b75aba906..748a156b30c 100644 --- a/zookeeper-command-line-client/pom.xml +++ b/zookeeper-command-line-client/pom.xml @@ -14,6 +14,7 @@ org.apache.zookeeper zookeeper + ${zookeeper.client.version} diff --git a/zookeeper-server/CMakeLists.txt b/zookeeper-server/CMakeLists.txt index 2065949abd4..2d8620f1028 100644 --- a/zookeeper-server/CMakeLists.txt +++ b/zookeeper-server/CMakeLists.txt @@ -1,2 +1,4 @@ # Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -install_fat_java_artifact(zookeeper-server) +add_subdirectory(zookeeper-server-common) +add_subdirectory(zookeeper-server-3.4) +add_subdirectory(zookeeper-server-3.5) diff --git a/zookeeper-server/pom.xml b/zookeeper-server/pom.xml index 3ccda41d1b9..fe182645681 100644 --- a/zookeeper-server/pom.xml +++ b/zookeeper-server/pom.xml @@ -9,48 +9,20 @@ ../parent/pom.xml zookeeper-server - container-plugin + pom 7-SNAPSHOT + + zookeeper-server-common + zookeeper-server-3.4 + zookeeper-server-3.5 + - - junit - junit - test - - - com.yahoo.vespa - defaults - ${project.version} - provided - com.yahoo.vespa container-dev ${project.version} provided - - com.yahoo.vespa - vespajlib - ${project.version} - provided - - - com.yahoo.vespa - vespalog - ${project.version} - provided - - - org.apache.zookeeper - zookeeper - - - - org.slf4j - slf4j-log4j12 - 1.7.5 - diff --git a/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java b/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java deleted file mode 100644 index 5a1f31a75c3..00000000000 --- a/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.zookeeper; - -/** - * Interface for a component that writes zookeeper config and starts a zookeeper server. - * - * @author Harald Musum - */ -public interface VespaZooKeeperServer { - -} diff --git a/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java b/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java deleted file mode 100644 index 5b4c0c11e80..00000000000 --- a/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.zookeeper; - -import com.google.inject.Inject; -import com.yahoo.cloud.config.ZookeeperServerConfig; -import com.yahoo.component.AbstractComponent; -import com.yahoo.log.LogLevel; -import static com.yahoo.vespa.defaults.Defaults.getDefaults; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Writes zookeeper config and starts zookeeper server. - * - * @author Ulf Lilleengen - * @author Harald Musum - */ -public class VespaZooKeeperServerImpl extends AbstractComponent implements Runnable, VespaZooKeeperServer { - - private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(VespaZooKeeperServerImpl.class.getName()); - private static final String ZOOKEEPER_JMX_LOG4J_DISABLE = "zookeeper.jmx.log4j.disable"; - static final String ZOOKEEPER_JUTE_MAX_BUFFER = "jute.maxbuffer"; - private final Thread zkServerThread; - private final ZookeeperServerConfig zookeeperServerConfig; - - VespaZooKeeperServerImpl(ZookeeperServerConfig zookeeperServerConfig, boolean startServer) { - this.zookeeperServerConfig = zookeeperServerConfig; - System.setProperty("zookeeper.jmx.log4j.disable", "true"); - System.setProperty("zookeeper.snapshot.trust.empty", Boolean.valueOf(zookeeperServerConfig.trustEmptySnapshot()).toString()); - System.setProperty(ZOOKEEPER_JUTE_MAX_BUFFER, Integer.valueOf(zookeeperServerConfig.juteMaxBuffer()).toString()); - - writeConfigToDisk(zookeeperServerConfig); - zkServerThread = new Thread(this, "zookeeper server"); - if (startServer) { - zkServerThread.start(); - } - } - - @Inject - public VespaZooKeeperServerImpl(ZookeeperServerConfig zookeeperServerConfig) { - this(zookeeperServerConfig, true); - } - - private void writeConfigToDisk(ZookeeperServerConfig config) { - String configFilePath = getDefaults().underVespaHome(config.zooKeeperConfigFile()); - new File(configFilePath).getParentFile().mkdirs(); - try (FileWriter writer = new FileWriter(configFilePath)) { - writer.write(transformConfigToString(config)); - writeMyIdFile(config); - } catch (IOException e) { - throw new RuntimeException("Error writing zookeeper config", e); - } - } - - private String transformConfigToString(ZookeeperServerConfig config) { - StringBuilder sb = new StringBuilder(); - sb.append("tickTime=").append(config.tickTime()).append("\n"); - sb.append("initLimit=").append(config.initLimit()).append("\n"); - sb.append("syncLimit=").append(config.syncLimit()).append("\n"); - sb.append("maxClientCnxns=").append(config.maxClientConnections()).append("\n"); - sb.append("snapCount=").append(config.snapshotCount()).append("\n"); - sb.append("dataDir=").append(getDefaults().underVespaHome(config.dataDir())).append("\n"); - sb.append("clientPort=").append(config.clientPort()).append("\n"); - sb.append("autopurge.purgeInterval=").append(config.autopurge().purgeInterval()).append("\n"); - sb.append("autopurge.snapRetainCount=").append(config.autopurge().snapRetainCount()).append("\n"); - // See http://zookeeper.apache.org/doc/r3.4.13/zookeeperAdmin.html#sc_zkCommands - // Includes all available commands in 3.4, except 'wchc' and 'wchp' - // Mandatory when using ZooKeeper 3.5 - sb.append("4lw.commands.whitelist=conf,cons,crst,dump,envi,mntr,ruok,srst,srvr,stat,wchs").append("\n"); - ensureThisServerIsRepresented(config.myid(), config.server()); - config.server().forEach(server -> addServerToCfg(sb, server)); - return sb.toString(); - } - - private void writeMyIdFile(ZookeeperServerConfig config) throws IOException { - if (config.server().size() > 1) { - try (FileWriter writer = new FileWriter(getDefaults().underVespaHome(config.myidFile()))) { - writer.write(config.myid() + "\n"); - } - } - } - - private void ensureThisServerIsRepresented(int myid, List servers) { - boolean found = false; - for (ZookeeperServerConfig.Server server : servers) { - if (myid == server.id()) { - found = true; - break; - } - } - if (!found) { - throw new RuntimeException("No id in zookeeper server list that corresponds to my id(" + myid + ")"); - } - } - - private void addServerToCfg(StringBuilder sb, ZookeeperServerConfig.Server server) { - sb.append("server.").append(server.id()).append("=").append(server.hostname()).append(":").append(server.quorumPort()).append(":").append(server.electionPort()).append("\n"); - } - - private void shutdown() { - zkServerThread.interrupt(); - try { - zkServerThread.join(); - } catch (InterruptedException e) { - log.log(LogLevel.WARNING, "Error joining server thread on shutdown", e); - } - } - - @Override - public void run() { - System.setProperty(ZOOKEEPER_JMX_LOG4J_DISABLE, "true"); - String[] args = new String[]{getDefaults().underVespaHome(zookeeperServerConfig.zooKeeperConfigFile())}; - log.log(LogLevel.DEBUG, "Starting ZooKeeper server with config file " + args[0]); - log.log(LogLevel.INFO, "Trying to establish ZooKeeper quorum (from " + zookeeperServerHostnames(zookeeperServerConfig) + ")"); - org.apache.zookeeper.server.quorum.QuorumPeerMain.main(args); - } - - @Override - public void deconstruct() { - shutdown(); - super.deconstruct(); - } - - private static Set zookeeperServerHostnames(ZookeeperServerConfig zookeeperServerConfig) { - return zookeeperServerConfig.server().stream().map(ZookeeperServerConfig.Server::hostname).collect(Collectors.toSet()); - } - -} diff --git a/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/package-info.java b/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/package-info.java deleted file mode 100644 index 470d1350f9c..00000000000 --- a/zookeeper-server/src/main/java/com/yahoo/vespa/zookeeper/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -package com.yahoo.vespa.zookeeper; - -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/zookeeper-server/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java b/zookeeper-server/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java deleted file mode 100644 index 1081c5fda61..00000000000 --- a/zookeeper-server/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.zookeeper; - -import com.yahoo.cloud.config.ZookeeperServerConfig; -import com.yahoo.io.IOUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - -import java.io.File; -import java.io.IOException; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static com.yahoo.vespa.defaults.Defaults.getDefaults; - -/** - * Tests the zookeeper server. - */ -public class VespaZooKeeperServerImplTest { - - @Rule - public TemporaryFolder folder = new TemporaryFolder(); - - @Test - public void config_is_written_correctly_when_one_server() throws IOException { - File cfgFile = folder.newFile(); - File idFile = folder.newFile(); - ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); - builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); - builder.myidFile(idFile.getAbsolutePath()); - builder.server(newServer(0, "foo", 123, 321)); - builder.myid(0); - createServer(builder); - validateConfigFileSingleHost(cfgFile); - validateIdFile(idFile, ""); - } - - @Test - public void config_is_written_correctly_when_multiple_servers() throws IOException { - File cfgFile = folder.newFile(); - File idFile = folder.newFile(); - ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); - builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); - builder.server(newServer(0, "foo", 123, 321)); - builder.server(newServer(1, "bar", 234, 432)); - builder.server(newServer(2, "baz", 345, 543)); - builder.myidFile(idFile.getAbsolutePath()); - builder.myid(1); - createServer(builder); - validateConfigFileMultipleHosts(cfgFile); - validateIdFile(idFile, "1\n"); - } - - private void createServer(ZookeeperServerConfig.Builder builder) { - new VespaZooKeeperServerImpl(new ZookeeperServerConfig(builder), false); - } - - @Test(expected = RuntimeException.class) - public void require_that_this_id_must_be_present_amongst_servers() { - ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); - builder.server(newServer(1, "bar", 234, 432)); - builder.server(newServer(2, "baz", 345, 543)); - builder.myid(0); - createServer(builder); - } - - @Test - public void juteMaxBufferCanBeSet() throws IOException { - ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); - builder.myid(0); - File idFile = folder.newFile(); - File cfgFile = folder.newFile(); - - builder.server(new ZookeeperServerConfig.Server.Builder().id(0).hostname("testhost")); - builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); - builder.myidFile(idFile.getAbsolutePath()); - - createServer(builder); - assertThat(System.getProperty(VespaZooKeeperServerImpl.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + new ZookeeperServerConfig(builder).juteMaxBuffer())); - - final int max_buffer = 1; - builder.juteMaxBuffer(max_buffer); - createServer(builder); - assertThat(System.getProperty(VespaZooKeeperServerImpl.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + max_buffer)); - } - - private ZookeeperServerConfig.Server.Builder newServer(int id, String hostName, int electionPort, int quorumPort) { - ZookeeperServerConfig.Server.Builder builder = new ZookeeperServerConfig.Server.Builder(); - builder.id(id); - builder.hostname(hostName); - builder.electionPort(electionPort); - builder.quorumPort(quorumPort); - return builder; - } - - private void validateIdFile(File idFile, String expected) throws IOException { - String actual = IOUtils.readFile(idFile); - assertThat(actual, is(expected)); - } - - private void validateConfigFileSingleHost(File cfgFile) throws IOException { - String expected = - "tickTime=2000\n" + - "initLimit=20\n" + - "syncLimit=15\n" + - "maxClientCnxns=0\n" + - "snapCount=50000\n" + - "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + - "clientPort=2181\n" + - "autopurge.purgeInterval=1\n" + - "autopurge.snapRetainCount=15\n" + - "4lw.commands.whitelist=conf,cons,crst,dump,envi,mntr,ruok,srst,srvr,stat,wchs\n" + - "server.0=foo:321:123\n"; - validateConfigFile(cfgFile, expected); - } - - private void validateConfigFileMultipleHosts(File cfgFile) throws IOException { - String expected = - "tickTime=2000\n" + - "initLimit=20\n" + - "syncLimit=15\n" + - "maxClientCnxns=0\n" + - "snapCount=50000\n" + - "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + - "clientPort=2181\n" + - "autopurge.purgeInterval=1\n" + - "autopurge.snapRetainCount=15\n" + - "4lw.commands.whitelist=conf,cons,crst,dump,envi,mntr,ruok,srst,srvr,stat,wchs\n" + - "server.0=foo:321:123\n" + - "server.1=bar:432:234\n" + - "server.2=baz:543:345\n"; - validateConfigFile(cfgFile, expected); - } - - private void validateConfigFile(File cfgFile, String expected) throws IOException { - String actual = IOUtils.readFile(cfgFile); - assertThat(actual, is(expected)); - } -} diff --git a/zookeeper-server/zookeeper-server-3.4/CMakeLists.txt b/zookeeper-server/zookeeper-server-3.4/CMakeLists.txt new file mode 100644 index 00000000000..d80b48c9093 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.4/CMakeLists.txt @@ -0,0 +1,2 @@ +# Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +install_fat_java_artifact(zookeeper-server-3.4) diff --git a/zookeeper-server/zookeeper-server-3.4/pom.xml b/zookeeper-server/zookeeper-server-3.4/pom.xml new file mode 100644 index 00000000000..fd437608b40 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.4/pom.xml @@ -0,0 +1,69 @@ + + + + 4.0.0 + + com.yahoo.vespa + zookeeper-server + 7-SNAPSHOT + ../pom.xml + + zookeeper-server-3.4 + container-plugin + 7-SNAPSHOT + + + com.yahoo.vespa + zookeeper-server-common + ${project.version} + + + org.apache.zookeeper + zookeeper + 3.4.14 + + + junit + junit + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -Xlint:all + -Werror + + + + + org.apache.maven.plugins + maven-surefire-plugin + + ${test.hide} + once + + + + org.apache.maven.plugins + maven-install-plugin + + true + + + + com.yahoo.vespa + bundle-plugin + true + + com.sun.management + zookeeper-server + + + + + diff --git a/zookeeper-server/zookeeper-server-3.4/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java b/zookeeper-server/zookeeper-server-3.4/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java new file mode 100644 index 00000000000..5b4c0c11e80 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.4/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java @@ -0,0 +1,133 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.zookeeper; + +import com.google.inject.Inject; +import com.yahoo.cloud.config.ZookeeperServerConfig; +import com.yahoo.component.AbstractComponent; +import com.yahoo.log.LogLevel; +import static com.yahoo.vespa.defaults.Defaults.getDefaults; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Writes zookeeper config and starts zookeeper server. + * + * @author Ulf Lilleengen + * @author Harald Musum + */ +public class VespaZooKeeperServerImpl extends AbstractComponent implements Runnable, VespaZooKeeperServer { + + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(VespaZooKeeperServerImpl.class.getName()); + private static final String ZOOKEEPER_JMX_LOG4J_DISABLE = "zookeeper.jmx.log4j.disable"; + static final String ZOOKEEPER_JUTE_MAX_BUFFER = "jute.maxbuffer"; + private final Thread zkServerThread; + private final ZookeeperServerConfig zookeeperServerConfig; + + VespaZooKeeperServerImpl(ZookeeperServerConfig zookeeperServerConfig, boolean startServer) { + this.zookeeperServerConfig = zookeeperServerConfig; + System.setProperty("zookeeper.jmx.log4j.disable", "true"); + System.setProperty("zookeeper.snapshot.trust.empty", Boolean.valueOf(zookeeperServerConfig.trustEmptySnapshot()).toString()); + System.setProperty(ZOOKEEPER_JUTE_MAX_BUFFER, Integer.valueOf(zookeeperServerConfig.juteMaxBuffer()).toString()); + + writeConfigToDisk(zookeeperServerConfig); + zkServerThread = new Thread(this, "zookeeper server"); + if (startServer) { + zkServerThread.start(); + } + } + + @Inject + public VespaZooKeeperServerImpl(ZookeeperServerConfig zookeeperServerConfig) { + this(zookeeperServerConfig, true); + } + + private void writeConfigToDisk(ZookeeperServerConfig config) { + String configFilePath = getDefaults().underVespaHome(config.zooKeeperConfigFile()); + new File(configFilePath).getParentFile().mkdirs(); + try (FileWriter writer = new FileWriter(configFilePath)) { + writer.write(transformConfigToString(config)); + writeMyIdFile(config); + } catch (IOException e) { + throw new RuntimeException("Error writing zookeeper config", e); + } + } + + private String transformConfigToString(ZookeeperServerConfig config) { + StringBuilder sb = new StringBuilder(); + sb.append("tickTime=").append(config.tickTime()).append("\n"); + sb.append("initLimit=").append(config.initLimit()).append("\n"); + sb.append("syncLimit=").append(config.syncLimit()).append("\n"); + sb.append("maxClientCnxns=").append(config.maxClientConnections()).append("\n"); + sb.append("snapCount=").append(config.snapshotCount()).append("\n"); + sb.append("dataDir=").append(getDefaults().underVespaHome(config.dataDir())).append("\n"); + sb.append("clientPort=").append(config.clientPort()).append("\n"); + sb.append("autopurge.purgeInterval=").append(config.autopurge().purgeInterval()).append("\n"); + sb.append("autopurge.snapRetainCount=").append(config.autopurge().snapRetainCount()).append("\n"); + // See http://zookeeper.apache.org/doc/r3.4.13/zookeeperAdmin.html#sc_zkCommands + // Includes all available commands in 3.4, except 'wchc' and 'wchp' + // Mandatory when using ZooKeeper 3.5 + sb.append("4lw.commands.whitelist=conf,cons,crst,dump,envi,mntr,ruok,srst,srvr,stat,wchs").append("\n"); + ensureThisServerIsRepresented(config.myid(), config.server()); + config.server().forEach(server -> addServerToCfg(sb, server)); + return sb.toString(); + } + + private void writeMyIdFile(ZookeeperServerConfig config) throws IOException { + if (config.server().size() > 1) { + try (FileWriter writer = new FileWriter(getDefaults().underVespaHome(config.myidFile()))) { + writer.write(config.myid() + "\n"); + } + } + } + + private void ensureThisServerIsRepresented(int myid, List servers) { + boolean found = false; + for (ZookeeperServerConfig.Server server : servers) { + if (myid == server.id()) { + found = true; + break; + } + } + if (!found) { + throw new RuntimeException("No id in zookeeper server list that corresponds to my id(" + myid + ")"); + } + } + + private void addServerToCfg(StringBuilder sb, ZookeeperServerConfig.Server server) { + sb.append("server.").append(server.id()).append("=").append(server.hostname()).append(":").append(server.quorumPort()).append(":").append(server.electionPort()).append("\n"); + } + + private void shutdown() { + zkServerThread.interrupt(); + try { + zkServerThread.join(); + } catch (InterruptedException e) { + log.log(LogLevel.WARNING, "Error joining server thread on shutdown", e); + } + } + + @Override + public void run() { + System.setProperty(ZOOKEEPER_JMX_LOG4J_DISABLE, "true"); + String[] args = new String[]{getDefaults().underVespaHome(zookeeperServerConfig.zooKeeperConfigFile())}; + log.log(LogLevel.DEBUG, "Starting ZooKeeper server with config file " + args[0]); + log.log(LogLevel.INFO, "Trying to establish ZooKeeper quorum (from " + zookeeperServerHostnames(zookeeperServerConfig) + ")"); + org.apache.zookeeper.server.quorum.QuorumPeerMain.main(args); + } + + @Override + public void deconstruct() { + shutdown(); + super.deconstruct(); + } + + private static Set zookeeperServerHostnames(ZookeeperServerConfig zookeeperServerConfig) { + return zookeeperServerConfig.server().stream().map(ZookeeperServerConfig.Server::hostname).collect(Collectors.toSet()); + } + +} diff --git a/zookeeper-server/zookeeper-server-3.4/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java b/zookeeper-server/zookeeper-server-3.4/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java new file mode 100644 index 00000000000..1081c5fda61 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.4/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java @@ -0,0 +1,140 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.zookeeper; + +import com.yahoo.cloud.config.ZookeeperServerConfig; +import com.yahoo.io.IOUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static com.yahoo.vespa.defaults.Defaults.getDefaults; + +/** + * Tests the zookeeper server. + */ +public class VespaZooKeeperServerImplTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void config_is_written_correctly_when_one_server() throws IOException { + File cfgFile = folder.newFile(); + File idFile = folder.newFile(); + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); + builder.myidFile(idFile.getAbsolutePath()); + builder.server(newServer(0, "foo", 123, 321)); + builder.myid(0); + createServer(builder); + validateConfigFileSingleHost(cfgFile); + validateIdFile(idFile, ""); + } + + @Test + public void config_is_written_correctly_when_multiple_servers() throws IOException { + File cfgFile = folder.newFile(); + File idFile = folder.newFile(); + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); + builder.server(newServer(0, "foo", 123, 321)); + builder.server(newServer(1, "bar", 234, 432)); + builder.server(newServer(2, "baz", 345, 543)); + builder.myidFile(idFile.getAbsolutePath()); + builder.myid(1); + createServer(builder); + validateConfigFileMultipleHosts(cfgFile); + validateIdFile(idFile, "1\n"); + } + + private void createServer(ZookeeperServerConfig.Builder builder) { + new VespaZooKeeperServerImpl(new ZookeeperServerConfig(builder), false); + } + + @Test(expected = RuntimeException.class) + public void require_that_this_id_must_be_present_amongst_servers() { + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.server(newServer(1, "bar", 234, 432)); + builder.server(newServer(2, "baz", 345, 543)); + builder.myid(0); + createServer(builder); + } + + @Test + public void juteMaxBufferCanBeSet() throws IOException { + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.myid(0); + File idFile = folder.newFile(); + File cfgFile = folder.newFile(); + + builder.server(new ZookeeperServerConfig.Server.Builder().id(0).hostname("testhost")); + builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); + builder.myidFile(idFile.getAbsolutePath()); + + createServer(builder); + assertThat(System.getProperty(VespaZooKeeperServerImpl.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + new ZookeeperServerConfig(builder).juteMaxBuffer())); + + final int max_buffer = 1; + builder.juteMaxBuffer(max_buffer); + createServer(builder); + assertThat(System.getProperty(VespaZooKeeperServerImpl.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + max_buffer)); + } + + private ZookeeperServerConfig.Server.Builder newServer(int id, String hostName, int electionPort, int quorumPort) { + ZookeeperServerConfig.Server.Builder builder = new ZookeeperServerConfig.Server.Builder(); + builder.id(id); + builder.hostname(hostName); + builder.electionPort(electionPort); + builder.quorumPort(quorumPort); + return builder; + } + + private void validateIdFile(File idFile, String expected) throws IOException { + String actual = IOUtils.readFile(idFile); + assertThat(actual, is(expected)); + } + + private void validateConfigFileSingleHost(File cfgFile) throws IOException { + String expected = + "tickTime=2000\n" + + "initLimit=20\n" + + "syncLimit=15\n" + + "maxClientCnxns=0\n" + + "snapCount=50000\n" + + "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + + "clientPort=2181\n" + + "autopurge.purgeInterval=1\n" + + "autopurge.snapRetainCount=15\n" + + "4lw.commands.whitelist=conf,cons,crst,dump,envi,mntr,ruok,srst,srvr,stat,wchs\n" + + "server.0=foo:321:123\n"; + validateConfigFile(cfgFile, expected); + } + + private void validateConfigFileMultipleHosts(File cfgFile) throws IOException { + String expected = + "tickTime=2000\n" + + "initLimit=20\n" + + "syncLimit=15\n" + + "maxClientCnxns=0\n" + + "snapCount=50000\n" + + "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + + "clientPort=2181\n" + + "autopurge.purgeInterval=1\n" + + "autopurge.snapRetainCount=15\n" + + "4lw.commands.whitelist=conf,cons,crst,dump,envi,mntr,ruok,srst,srvr,stat,wchs\n" + + "server.0=foo:321:123\n" + + "server.1=bar:432:234\n" + + "server.2=baz:543:345\n"; + validateConfigFile(cfgFile, expected); + } + + private void validateConfigFile(File cfgFile, String expected) throws IOException { + String actual = IOUtils.readFile(cfgFile); + assertThat(actual, is(expected)); + } +} diff --git a/zookeeper-server/zookeeper-server-3.5/CMakeLists.txt b/zookeeper-server/zookeeper-server-3.5/CMakeLists.txt new file mode 100644 index 00000000000..6094573ee24 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.5/CMakeLists.txt @@ -0,0 +1,2 @@ +# Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +install_fat_java_artifact(zookeeper-server-3.5) diff --git a/zookeeper-server/zookeeper-server-3.5/pom.xml b/zookeeper-server/zookeeper-server-3.5/pom.xml new file mode 100644 index 00000000000..fd83c62a3e3 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.5/pom.xml @@ -0,0 +1,69 @@ + + + + 4.0.0 + + com.yahoo.vespa + zookeeper-server + 7-SNAPSHOT + ../pom.xml + + zookeeper-server-3.5 + container-plugin + 7-SNAPSHOT + + + com.yahoo.vespa + zookeeper-server-common + ${project.version} + + + org.apache.zookeeper + zookeeper + 3.5.6 + + + junit + junit + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -Xlint:all + -Werror + + + + + org.apache.maven.plugins + maven-surefire-plugin + + ${test.hide} + once + + + + org.apache.maven.plugins + maven-install-plugin + + true + + + + com.yahoo.vespa + bundle-plugin + true + + com.sun.management + zookeeper-server + + + + + diff --git a/zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java b/zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java new file mode 100644 index 00000000000..9cb87efa3c0 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.5/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImpl.java @@ -0,0 +1,135 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.zookeeper; + +import com.google.inject.Inject; +import com.yahoo.cloud.config.ZookeeperServerConfig; +import com.yahoo.component.AbstractComponent; +import com.yahoo.log.LogLevel; +import static com.yahoo.vespa.defaults.Defaults.getDefaults; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Writes zookeeper config and starts zookeeper server. + * + * @author Ulf Lilleengen + * @author Harald Musum + */ +public class VespaZooKeeperServerImpl extends AbstractComponent implements Runnable, VespaZooKeeperServer { + + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(VespaZooKeeperServerImpl.class.getName()); + private static final String ZOOKEEPER_JMX_LOG4J_DISABLE = "zookeeper.jmx.log4j.disable"; + static final String ZOOKEEPER_JUTE_MAX_BUFFER = "jute.maxbuffer"; + private final Thread zkServerThread; + private final ZookeeperServerConfig zookeeperServerConfig; + + VespaZooKeeperServerImpl(ZookeeperServerConfig zookeeperServerConfig, boolean startServer) { + this.zookeeperServerConfig = zookeeperServerConfig; + System.setProperty("zookeeper.jmx.log4j.disable", "true"); + System.setProperty("zookeeper.snapshot.trust.empty", Boolean.valueOf(zookeeperServerConfig.trustEmptySnapshot()).toString()); + System.setProperty(ZOOKEEPER_JUTE_MAX_BUFFER, Integer.valueOf(zookeeperServerConfig.juteMaxBuffer()).toString()); + + writeConfigToDisk(zookeeperServerConfig); + zkServerThread = new Thread(this, "zookeeper server"); + if (startServer) { + zkServerThread.start(); + } + } + + @Inject + public VespaZooKeeperServerImpl(ZookeeperServerConfig zookeeperServerConfig) { + this(zookeeperServerConfig, true); + } + + private void writeConfigToDisk(ZookeeperServerConfig config) { + String configFilePath = getDefaults().underVespaHome(config.zooKeeperConfigFile()); + new File(configFilePath).getParentFile().mkdirs(); + try (FileWriter writer = new FileWriter(configFilePath)) { + writer.write(transformConfigToString(config)); + writeMyIdFile(config); + } catch (IOException e) { + throw new RuntimeException("Error writing zookeeper config", e); + } + } + + private String transformConfigToString(ZookeeperServerConfig config) { + StringBuilder sb = new StringBuilder(); + sb.append("tickTime=").append(config.tickTime()).append("\n"); + sb.append("initLimit=").append(config.initLimit()).append("\n"); + sb.append("syncLimit=").append(config.syncLimit()).append("\n"); + sb.append("maxClientCnxns=").append(config.maxClientConnections()).append("\n"); + sb.append("snapCount=").append(config.snapshotCount()).append("\n"); + sb.append("dataDir=").append(getDefaults().underVespaHome(config.dataDir())).append("\n"); + sb.append("clientPort=").append(config.clientPort()).append("\n"); + sb.append("autopurge.purgeInterval=").append(config.autopurge().purgeInterval()).append("\n"); + sb.append("autopurge.snapRetainCount=").append(config.autopurge().snapRetainCount()).append("\n"); + // See http://zookeeper.apache.org/doc/r3.5.5/zookeeperAdmin.html#sc_zkCommands + // Includes all available commands in 3.5, except 'wchc' and 'wchp' + sb.append("4lw.commands.whitelist=conf,cons,crst,dirs,dump,envi,mntr,ruok,srst,srvr,stat,wchs").append("\n"); + sb.append("admin.enableServer=false").append("\n"); + // Need NettyServerCnxnFactory to be able to use TLS for communication + sb.append("serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory").append("\n"); + ensureThisServerIsRepresented(config.myid(), config.server()); + config.server().forEach(server -> addServerToCfg(sb, server)); + return sb.toString(); + } + + private void writeMyIdFile(ZookeeperServerConfig config) throws IOException { + if (config.server().size() > 1) { + try (FileWriter writer = new FileWriter(getDefaults().underVespaHome(config.myidFile()))) { + writer.write(config.myid() + "\n"); + } + } + } + + private void ensureThisServerIsRepresented(int myid, List servers) { + boolean found = false; + for (ZookeeperServerConfig.Server server : servers) { + if (myid == server.id()) { + found = true; + break; + } + } + if (!found) { + throw new RuntimeException("No id in zookeeper server list that corresponds to my id(" + myid + ")"); + } + } + + private void addServerToCfg(StringBuilder sb, ZookeeperServerConfig.Server server) { + sb.append("server.").append(server.id()).append("=").append(server.hostname()).append(":").append(server.quorumPort()).append(":").append(server.electionPort()).append("\n"); + } + + private void shutdown() { + zkServerThread.interrupt(); + try { + zkServerThread.join(); + } catch (InterruptedException e) { + log.log(LogLevel.WARNING, "Error joining server thread on shutdown", e); + } + } + + @Override + public void run() { + System.setProperty(ZOOKEEPER_JMX_LOG4J_DISABLE, "true"); + String[] args = new String[]{getDefaults().underVespaHome(zookeeperServerConfig.zooKeeperConfigFile())}; + log.log(LogLevel.INFO, "Starting ZooKeeper server with config file " + args[0] + + ". Trying to establish ZooKeeper quorum (members: " + zookeeperServerHostnames(zookeeperServerConfig) + ")"); + org.apache.zookeeper.server.quorum.QuorumPeerMain.main(args); + } + + @Override + public void deconstruct() { + shutdown(); + super.deconstruct(); + } + + private static Set zookeeperServerHostnames(ZookeeperServerConfig zookeeperServerConfig) { + return zookeeperServerConfig.server().stream().map(ZookeeperServerConfig.Server::hostname).collect(Collectors.toSet()); + } + +} diff --git a/zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java b/zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java new file mode 100644 index 00000000000..19690bff963 --- /dev/null +++ b/zookeeper-server/zookeeper-server-3.5/src/test/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServerImplTest.java @@ -0,0 +1,144 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.zookeeper; + +import com.yahoo.cloud.config.ZookeeperServerConfig; +import com.yahoo.io.IOUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static com.yahoo.vespa.defaults.Defaults.getDefaults; + +/** + * Tests the zookeeper server. + */ +public class VespaZooKeeperServerImplTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void config_is_written_correctly_when_one_server() throws IOException { + File cfgFile = folder.newFile(); + File idFile = folder.newFile(); + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); + builder.myidFile(idFile.getAbsolutePath()); + builder.server(newServer(0, "foo", 123, 321)); + builder.myid(0); + createServer(builder); + validateConfigFileSingleHost(cfgFile); + validateIdFile(idFile, ""); + } + + @Test + public void config_is_written_correctly_when_multiple_servers() throws IOException { + File cfgFile = folder.newFile(); + File idFile = folder.newFile(); + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); + builder.server(newServer(0, "foo", 123, 321)); + builder.server(newServer(1, "bar", 234, 432)); + builder.server(newServer(2, "baz", 345, 543)); + builder.myidFile(idFile.getAbsolutePath()); + builder.myid(1); + createServer(builder); + validateConfigFileMultipleHosts(cfgFile); + validateIdFile(idFile, "1\n"); + } + + private void createServer(ZookeeperServerConfig.Builder builder) { + new VespaZooKeeperServerImpl(new ZookeeperServerConfig(builder), false); + } + + @Test(expected = RuntimeException.class) + public void require_that_this_id_must_be_present_amongst_servers() { + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.server(newServer(1, "bar", 234, 432)); + builder.server(newServer(2, "baz", 345, 543)); + builder.myid(0); + createServer(builder); + } + + @Test + public void juteMaxBufferCanBeSet() throws IOException { + ZookeeperServerConfig.Builder builder = new ZookeeperServerConfig.Builder(); + builder.myid(0); + File idFile = folder.newFile(); + File cfgFile = folder.newFile(); + + builder.server(new ZookeeperServerConfig.Server.Builder().id(0).hostname("testhost")); + builder.zooKeeperConfigFile(cfgFile.getAbsolutePath()); + builder.myidFile(idFile.getAbsolutePath()); + + createServer(builder); + assertThat(System.getProperty(VespaZooKeeperServerImpl.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + new ZookeeperServerConfig(builder).juteMaxBuffer())); + + final int max_buffer = 1; + builder.juteMaxBuffer(max_buffer); + createServer(builder); + assertThat(System.getProperty(VespaZooKeeperServerImpl.ZOOKEEPER_JUTE_MAX_BUFFER), is("" + max_buffer)); + } + + private ZookeeperServerConfig.Server.Builder newServer(int id, String hostName, int electionPort, int quorumPort) { + ZookeeperServerConfig.Server.Builder builder = new ZookeeperServerConfig.Server.Builder(); + builder.id(id); + builder.hostname(hostName); + builder.electionPort(electionPort); + builder.quorumPort(quorumPort); + return builder; + } + + private void validateIdFile(File idFile, String expected) throws IOException { + String actual = IOUtils.readFile(idFile); + assertThat(actual, is(expected)); + } + + private void validateConfigFileSingleHost(File cfgFile) throws IOException { + String expected = + "tickTime=2000\n" + + "initLimit=20\n" + + "syncLimit=15\n" + + "maxClientCnxns=0\n" + + "snapCount=50000\n" + + "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + + "clientPort=2181\n" + + "autopurge.purgeInterval=1\n" + + "autopurge.snapRetainCount=15\n" + + "4lw.commands.whitelist=conf,cons,crst,dirs,dump,envi,mntr,ruok,srst,srvr,stat,wchs\n" + + "admin.enableServer=false\n" + + "serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory\n" + + "server.0=foo:321:123\n"; + validateConfigFile(cfgFile, expected); + } + + private void validateConfigFileMultipleHosts(File cfgFile) throws IOException { + String expected = + "tickTime=2000\n" + + "initLimit=20\n" + + "syncLimit=15\n" + + "maxClientCnxns=0\n" + + "snapCount=50000\n" + + "dataDir=" + getDefaults().underVespaHome("var/zookeeper") + "\n" + + "clientPort=2181\n" + + "autopurge.purgeInterval=1\n" + + "autopurge.snapRetainCount=15\n" + + "4lw.commands.whitelist=conf,cons,crst,dirs,dump,envi,mntr,ruok,srst,srvr,stat,wchs\n" + + "admin.enableServer=false\n" + + "serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory\n" + + "server.0=foo:321:123\n" + + "server.1=bar:432:234\n" + + "server.2=baz:543:345\n"; + validateConfigFile(cfgFile, expected); + } + + private void validateConfigFile(File cfgFile, String expected) throws IOException { + String actual = IOUtils.readFile(cfgFile); + assertThat(actual, is(expected)); + } +} diff --git a/zookeeper-server/zookeeper-server-common/CMakeLists.txt b/zookeeper-server/zookeeper-server-common/CMakeLists.txt new file mode 100644 index 00000000000..fd467aca067 --- /dev/null +++ b/zookeeper-server/zookeeper-server-common/CMakeLists.txt @@ -0,0 +1,2 @@ +# Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +install_fat_java_artifact(zookeeper-server-common) diff --git a/zookeeper-server/zookeeper-server-common/pom.xml b/zookeeper-server/zookeeper-server-common/pom.xml new file mode 100644 index 00000000000..66e5bc2075c --- /dev/null +++ b/zookeeper-server/zookeeper-server-common/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + com.yahoo.vespa + zookeeper-server + 7-SNAPSHOT + ../pom.xml + + zookeeper-server-common + container-plugin + 7-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -Xlint:all + -Werror + + + + + org.apache.maven.plugins + maven-surefire-plugin + + ${test.hide} + once + + + + org.apache.maven.plugins + maven-install-plugin + + true + + + + com.yahoo.vespa + bundle-plugin + true + + com.sun.management + zookeeper-server + + + + + diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java new file mode 100644 index 00000000000..5a1f31a75c3 --- /dev/null +++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/VespaZooKeeperServer.java @@ -0,0 +1,11 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.zookeeper; + +/** + * Interface for a component that writes zookeeper config and starts a zookeeper server. + * + * @author Harald Musum + */ +public interface VespaZooKeeperServer { + +} diff --git a/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/package-info.java b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/package-info.java new file mode 100644 index 00000000000..470d1350f9c --- /dev/null +++ b/zookeeper-server/zookeeper-server-common/src/main/java/com/yahoo/vespa/zookeeper/package-info.java @@ -0,0 +1,5 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.vespa.zookeeper; + +import com.yahoo.osgi.annotation.ExportPackage; -- cgit v1.2.3