This is an automated email from the ASF dual-hosted git repository.

eolivelli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/curator.git


The following commit(s) were added to refs/heads/master by this push:
     new 4e19ca12 CURATOR-587. Use ZooKeeperServerEmbedded to start 
TestingServer (#434)
4e19ca12 is described below

commit 4e19ca12a0ed5eced2ddcc026399382731b1ce19
Author: tison <[email protected]>
AuthorDate: Wed Aug 31 14:32:08 2022 +0800

    CURATOR-587. Use ZooKeeperServerEmbedded to start TestingServer (#434)
---
 curator-framework/pom.xml                          |  6 ++
 .../curator/framework/imps/TestReadOnly.java       | 45 ++++-------
 .../recipes/leader/ChaosMonkeyCnxnFactory.java     | 10 ++-
 .../apache/curator/test/QuorumConfigBuilder.java   | 32 ++++----
 .../apache/curator/test/TestingQuorumPeerMain.java | 48 +++++++++---
 .../apache/curator/test/TestingZooKeeperMain.java  | 63 +++++++++++-----
 .../curator/test/TestingZooKeeperServer.java       | 66 ++++++++--------
 .../org/apache/curator/test/ZooKeeperMainFace.java |  8 +-
 .../test/ZooKeeperServerEmbeddedAdapter.java       | 88 ++++++++++++++++++++++
 .../org/apache/curator/test/TestTestingServer.java |  3 +-
 10 files changed, 251 insertions(+), 118 deletions(-)

diff --git a/curator-framework/pom.xml b/curator-framework/pom.xml
index ebc55a84..62d12d83 100644
--- a/curator-framework/pom.xml
+++ b/curator-framework/pom.xml
@@ -56,6 +56,12 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-core</artifactId>
diff --git 
a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReadOnly.java
 
b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReadOnly.java
index 21a9130a..1d1d2d04 100644
--- 
a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReadOnly.java
+++ 
b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestReadOnly.java
@@ -19,6 +19,7 @@
 
 package org.apache.curator.framework.imps;
 
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import com.google.common.collect.Queues;
@@ -69,12 +70,9 @@ public class TestReadOnly extends BaseClassForTests
             client = 
CuratorFrameworkFactory.newClient(cluster.getConnectString(), timing.session(), 
timing.connection(), new RetryOneTime(100));
             client.start();
             client.checkExists().forPath("/");
-            client.getConnectionStateListenable().addListener(new 
ConnectionStateListener() {
-                @Override
-                public void stateChanged(CuratorFramework client, 
ConnectionState newState) {
-                    if (newState == ConnectionState.LOST) {
-                        lostLatch.countDown();
-                    }
+            client.getConnectionStateListenable().addListener((client1, 
newState) -> {
+                if (newState == ConnectionState.LOST) {
+                    lostLatch.countDown();
                 }
             });
 
@@ -95,23 +93,13 @@ public class TestReadOnly extends BaseClassForTests
                 .build();
 
             final BlockingQueue<ConnectionState> states = 
Queues.newLinkedBlockingQueue();
-            client.getConnectionStateListenable().addListener
-            (
-                new ConnectionStateListener()
-                {
-                    @Override
-                    public void stateChanged(CuratorFramework client, 
ConnectionState newState)
-                    {
-                        states.add(newState);
-                    }
-                }
-            );
+            client.getConnectionStateListenable().addListener((client12, 
newState) -> states.add(newState));
             client.start();
 
             client.checkExists().forPath("/");
 
             ConnectionState state = 
states.poll(timing.forWaiting().milliseconds(), TimeUnit.MILLISECONDS);
-            assertEquals(state, ConnectionState.READ_ONLY);
+            assertThat(state).isEqualTo(ConnectionState.READ_ONLY);
         }
         finally
         {
@@ -136,19 +124,14 @@ public class TestReadOnly extends BaseClassForTests
 
             final CountDownLatch readOnlyLatch = new CountDownLatch(1);
             final CountDownLatch reconnectedLatch = new CountDownLatch(1);
-            ConnectionStateListener listener = new ConnectionStateListener()
-            {
-                @Override
-                public void stateChanged(CuratorFramework client, 
ConnectionState newState)
+            ConnectionStateListener listener = (client1, newState) -> {
+                if ( newState == ConnectionState.READ_ONLY )
+                {
+                    readOnlyLatch.countDown();
+                }
+                else if ( newState == ConnectionState.RECONNECTED )
                 {
-                    if ( newState == ConnectionState.READ_ONLY )
-                    {
-                        readOnlyLatch.countDown();
-                    }
-                    else if ( newState == ConnectionState.RECONNECTED )
-                    {
-                        reconnectedLatch.countDown();
-                    }
+                    reconnectedLatch.countDown();
                 }
             };
             client.getConnectionStateListenable().addListener(listener);
@@ -177,7 +160,7 @@ public class TestReadOnly extends BaseClassForTests
     }
 
     @Override
-    protected void createServer() throws Exception
+    protected void createServer()
     {
         // NOP
     }
diff --git 
a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java
 
b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java
index 07e9a178..aaaf43c1 100644
--- 
a/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java
+++ 
b/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java
@@ -27,6 +27,7 @@ import org.apache.zookeeper.server.ByteBufferInputStream;
 import org.apache.zookeeper.server.NIOServerCnxnFactory;
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.ZooKeeperServerShutdownHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import java.io.IOException;
@@ -76,10 +77,6 @@ public class ChaosMonkeyCnxnFactory extends 
NIOServerCnxnFactory
             {
                 ((TestingZooKeeperMain.TestZooKeeperServer)zks).noteStartup();
             }
-            else
-            {
-                throw new RuntimeException("Unknown ZooKeeperServer: " + 
zks.getClass());
-            }
         }
 
         @Override
@@ -123,5 +120,10 @@ public class ChaosMonkeyCnxnFactory extends 
NIOServerCnxnFactory
                 }
             }
         }
+
+        @Override
+        public ZooKeeperServerShutdownHandler getZkShutdownHandler() {
+            return zks.getZkShutdownHandler();
+        }
     }
 }
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/QuorumConfigBuilder.java 
b/curator-test/src/main/java/org/apache/curator/test/QuorumConfigBuilder.java
index 2300efc9..42f7b27b 100644
--- 
a/curator-test/src/main/java/org/apache/curator/test/QuorumConfigBuilder.java
+++ 
b/curator-test/src/main/java/org/apache/curator/test/QuorumConfigBuilder.java
@@ -96,6 +96,22 @@ public class QuorumConfigBuilder implements Closeable
     }
 
     public QuorumPeerConfig buildConfig(int instanceIndex) throws Exception
+    {
+        Properties properties = buildConfigProperties(instanceIndex);
+        QuorumPeerConfig config = new QuorumPeerConfig()
+        {
+            {
+                if ( fakeConfigFile != null )
+                {
+                    configFileStr = fakeConfigFile.getPath();
+                }
+            }
+        };
+        config.parseProperties(properties);
+        return config;
+    }
+
+    public Properties buildConfigProperties(int instanceIndex) throws Exception
     {
         boolean isCluster = (instanceSpecs.size() > 1);
         InstanceSpec spec = instanceSpecs.get(instanceIndex);
@@ -131,21 +147,9 @@ public class QuorumConfigBuilder implements Closeable
         }
         Map<String,Object> customProperties = spec.getCustomProperties();
         if (customProperties != null) {
-            for (Map.Entry<String,Object> property : 
customProperties.entrySet()) {
-                properties.put(property.getKey(), property.getValue());
-            }
+            properties.putAll(customProperties);
         }
 
-        QuorumPeerConfig config = new QuorumPeerConfig()
-        {
-            {
-                if ( fakeConfigFile != null )
-                {
-                    configFileStr = fakeConfigFile.getPath();
-                }
-            }
-        };
-        config.parseProperties(properties);
-        return config;
+        return properties;
     }
 }
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java 
b/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java
index 49d47c54..a54e8cb3 100644
--- 
a/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java
+++ 
b/curator-test/src/main/java/org/apache/curator/test/TestingQuorumPeerMain.java
@@ -18,17 +18,23 @@
  */
 package org.apache.curator.test;
 
+import java.lang.reflect.Field;
+import java.nio.channels.ServerSocketChannel;
 import org.apache.zookeeper.server.ServerCnxnFactory;
 import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
 import org.apache.zookeeper.server.quorum.QuorumPeerMain;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.nio.channels.ServerSocketChannel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 class TestingQuorumPeerMain extends QuorumPeerMain implements ZooKeeperMainFace
 {
+    private static final Logger log = 
LoggerFactory.getLogger(TestingQuorumPeerMain.class);
     private volatile boolean isClosed = false;
 
+    private volatile QuorumConfigBuilder configBuilder;
+    private volatile int instanceIndex;
+
     @Override
     public void kill()
     {
@@ -54,11 +60,6 @@ class TestingQuorumPeerMain extends QuorumPeerMain 
implements ZooKeeperMainFace
         }
     }
 
-    public QuorumPeer getTestingQuorumPeer()
-    {
-        return quorumPeer;
-    }
-
     @Override
     public void close()
     {
@@ -69,8 +70,7 @@ class TestingQuorumPeerMain extends QuorumPeerMain implements 
ZooKeeperMainFace
         }
     }
 
-    @Override
-    public void blockUntilStarted()
+    private void blockUntilStarted()
     {
         long startTime = System.currentTimeMillis();
         while ( (quorumPeer == null) && ((System.currentTimeMillis() - 
startTime) <= TestingZooKeeperMain.MAX_WAIT_MS) )
@@ -90,4 +90,32 @@ class TestingQuorumPeerMain extends QuorumPeerMain 
implements ZooKeeperMainFace
             throw new FailedServerStartException("quorumPeer never got set");
         }
     }
+
+    @Override
+    public void configure(QuorumConfigBuilder configBuilder, int 
instanceIndex) {
+        this.configBuilder = configBuilder;
+        this.instanceIndex = instanceIndex;
+    }
+
+    @Override
+    public QuorumPeerConfig getConfig() throws Exception {
+        if (configBuilder != null) {
+            return configBuilder.buildConfig(instanceIndex);
+        }
+
+        return null;
+    }
+
+    @Override
+    public void start() {
+        new Thread(() -> {
+            try {
+                runFromConfig(getConfig());
+            } catch (Exception e) {
+                log.error("From testing server (random state: {}) for 
instance: {}", configBuilder.isFromRandom(), 
configBuilder.getInstanceSpec(instanceIndex), e);
+            }
+        }).start();
+
+        blockUntilStarted();
+    }
 }
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java 
b/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java
index b1a873a1..646cdc4f 100644
--- 
a/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java
+++ 
b/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java
@@ -19,6 +19,15 @@
 
 package org.apache.curator.test;
 
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.channels.ServerSocketChannel;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 import org.apache.zookeeper.jmx.MBeanRegistry;
 import org.apache.zookeeper.jmx.ZKMBeanInfo;
 import org.apache.zookeeper.server.ContainerManager;
@@ -31,27 +40,19 @@ import 
org.apache.zookeeper.server.persistence.FileTxnSnapLog;
 import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import javax.management.JMException;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.channels.ServerSocketChannel;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
 
 public class TestingZooKeeperMain implements ZooKeeperMainFace
 {
     private static final Logger log = 
LoggerFactory.getLogger(TestingZooKeeperMain.class);
 
     private final CountDownLatch latch = new CountDownLatch(1);
-    private final AtomicReference<Exception> startingException = new 
AtomicReference<Exception>(null);
+    private final AtomicReference<Exception> startingException = new 
AtomicReference<>(null);
 
     private volatile ServerCnxnFactory cnxnFactory;
     private volatile TestZooKeeperServer zkServer;
     private volatile ContainerManager containerManager;
+    private volatile QuorumConfigBuilder configBuilder;
+    private volatile int instanceIndex;
 
     private static final Timing timing = new Timing();
 
@@ -97,12 +98,16 @@ public class TestingZooKeeperMain implements 
ZooKeeperMainFace
         }
     }
 
-    TestZooKeeperServer getZkServer() {
-        return zkServer;
+    @Override
+    public QuorumPeerConfig getConfig() throws Exception {
+        if (configBuilder != null) {
+            return configBuilder.buildConfig(instanceIndex);
+        }
+
+        return null;
     }
 
-    @Override
-    public void runFromConfig(QuorumPeerConfig config) throws Exception
+    private void runFromConfig(QuorumPeerConfig config) throws Exception
     {
         try
         {
@@ -111,7 +116,7 @@ public class TestingZooKeeperMain implements 
ZooKeeperMainFace
             MBeanRegistry nopMBeanRegistry = new MBeanRegistry()
             {
                 @Override
-                public void register(ZKMBeanInfo bean, ZKMBeanInfo parent) 
throws JMException
+                public void register(ZKMBeanInfo bean, ZKMBeanInfo parent)
                 {
                     // NOP
                 }
@@ -142,9 +147,7 @@ public class TestingZooKeeperMain implements 
ZooKeeperMainFace
         }
     }
 
-    @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
-    @Override
-    public void blockUntilStarted()
+    private void blockUntilStarted()
     {
         if (!timing.awaitLatch(latch))
         {
@@ -267,6 +270,28 @@ public class TestingZooKeeperMain implements 
ZooKeeperMainFace
         }
     }
 
+    @Override
+    public void configure(QuorumConfigBuilder configBuilder, int 
instanceIndex) {
+        this.configBuilder = configBuilder;
+        this.instanceIndex = instanceIndex;
+    }
+
+    @Override
+    public void start() {
+        new Thread(() -> {
+            try
+            {
+                runFromConfig(getConfig());
+            }
+            catch ( Exception e )
+            {
+                log.error(String.format("From testing server (random state: 
%s) for instance: %s", String.valueOf(configBuilder.isFromRandom()), 
configBuilder.getInstanceSpec(instanceIndex)), e);
+            }
+        }, "zk-main-thread").start();
+
+        blockUntilStarted();
+    }
+
     public static class TestZooKeeperServer extends ZooKeeperServer
     {
         private final FileTxnSnapLog txnLog;
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperServer.java
 
b/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperServer.java
index e80566ad..42d94fd4 100644
--- 
a/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperServer.java
+++ 
b/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperServer.java
@@ -19,26 +19,37 @@
 
 package org.apache.curator.test;
 
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.concurrent.atomic.AtomicReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Thanks to Jeremie BORDIER (ahfeel) for this code
  */
 public class TestingZooKeeperServer implements Closeable
 {
-    private static final Logger logger = 
LoggerFactory.getLogger(TestingZooKeeperServer.class);
+    private static final Logger log = 
LoggerFactory.getLogger(TestingZooKeeperServer.class);
+    private static final boolean hasZooKeeperServerEmbedded;
 
+    private final AtomicReference<State> state = new 
AtomicReference<>(State.LATENT);
     private final QuorumConfigBuilder configBuilder;
     private final int thisInstanceIndex;
     private volatile ZooKeeperMainFace main;
-    private final AtomicReference<State> state = new 
AtomicReference<State>(State.LATENT);
+
+    static {
+        boolean localHasZooKeeperServerEmbedded;
+        try {
+            
Class.forName("org.apache.zookeeper.server.embedded.ZooKeeperServerEmbedded");
+            localHasZooKeeperServerEmbedded = true;
+        } catch (Throwable t) {
+            localHasZooKeeperServerEmbedded = false;
+            log.info("ZooKeeperServerEmbedded is not available in the version 
of the ZooKeeper library being used");
+        }
+        hasZooKeeperServerEmbedded = localHasZooKeeperServerEmbedded;
+    }
 
     ZooKeeperMainFace getMain() {
         return main;
@@ -60,20 +71,22 @@ public class TestingZooKeeperServer implements Closeable
 
         this.configBuilder = configBuilder;
         this.thisInstanceIndex = thisInstanceIndex;
-        main = isCluster() ? new TestingQuorumPeerMain() : new 
TestingZooKeeperMain();
+        main = createServerMain();
+    }
+
+    private ZooKeeperMainFace createServerMain() {
+        if (hasZooKeeperServerEmbedded) {
+            return new ZooKeeperServerEmbeddedAdapter();
+        } else if (isCluster()) {
+            return new TestingQuorumPeerMain();
+        } else {
+            return new TestingZooKeeperMain();
+        }
     }
 
     private boolean isCluster() {
         return configBuilder.size() > 1;
     }
-    
-    public QuorumPeer getQuorumPeer()
-    {
-        if (isCluster()) {
-            return ((TestingQuorumPeerMain) main).getTestingQuorumPeer();
-        }
-        throw new UnsupportedOperationException();
-    }
 
     public Collection<InstanceSpec> getInstanceSpecs()
     {
@@ -91,8 +104,6 @@ public class TestingZooKeeperServer implements Closeable
      * started again. If it is not running (in a LATENT or STOPPED state) then
      * it will be restarted. If it is in a CLOSED state then an exception will
      * be thrown.
-     *
-     * @throws Exception
      */
     public void restart() throws Exception
     {
@@ -111,7 +122,7 @@ public class TestingZooKeeperServer implements Closeable
         // Set to a LATENT state so we can restart
         state.set(State.LATENT);
 
-        main = isCluster() ? new TestingQuorumPeerMain() : new 
TestingZooKeeperMain();
+        main = createServerMain();
         start();
     }
 
@@ -152,22 +163,7 @@ public class TestingZooKeeperServer implements Closeable
             return;
         }
 
-        new Thread(new Runnable()
-        {
-            public void run()
-            {
-                try
-                {
-                    QuorumPeerConfig config = 
configBuilder.buildConfig(thisInstanceIndex);
-                    main.runFromConfig(config);
-                }
-                catch ( Exception e )
-                {
-                    logger.error(String.format("From testing server (random 
state: %s) for instance: %s", String.valueOf(configBuilder.isFromRandom()), 
getInstanceSpec()), e);
-                }
-            }
-        }).start();
-
-        main.blockUntilStarted();
+        main.configure(configBuilder, thisInstanceIndex);
+        main.start();
     }
 }
\ No newline at end of file
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java 
b/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java
index 904e601d..5b8521fe 100644
--- a/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java
+++ b/curator-test/src/main/java/org/apache/curator/test/ZooKeeperMainFace.java
@@ -18,14 +18,16 @@
  */
 package org.apache.curator.test;
 
-import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
 import java.io.Closeable;
+import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
 
 public interface ZooKeeperMainFace extends Closeable
 {
-    void runFromConfig(QuorumPeerConfig config) throws Exception;
+    void configure(QuorumConfigBuilder config, int instanceIndex) throws 
Exception;
 
-    void blockUntilStarted();
+    void start();
 
     void kill();
+
+    QuorumPeerConfig getConfig() throws Exception;
 }
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/ZooKeeperServerEmbeddedAdapter.java
 
b/curator-test/src/main/java/org/apache/curator/test/ZooKeeperServerEmbeddedAdapter.java
new file mode 100644
index 00000000..0e8aeb07
--- /dev/null
+++ 
b/curator-test/src/main/java/org/apache/curator/test/ZooKeeperServerEmbeddedAdapter.java
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.curator.test;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.Duration;
+import java.util.Properties;
+import org.apache.zookeeper.server.embedded.ZooKeeperServerEmbedded;
+import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ZooKeeperServerEmbeddedAdapter implements ZooKeeperMainFace {
+    private static final Logger log = 
LoggerFactory.getLogger(ZooKeeperServerEmbeddedAdapter.class);
+    private static final Duration DEFAULT_STARTUP_TIMEOUT = 
Duration.ofMinutes(1);
+
+    private volatile ZooKeeperServerEmbedded zooKeeperEmbedded;
+    private volatile QuorumConfigBuilder configBuilder;
+    private volatile int instanceIndex;
+
+    @Override
+    public void configure(QuorumConfigBuilder config, int instanceIndex) 
throws Exception {
+        this.configBuilder = config;
+        this.instanceIndex = instanceIndex;
+
+        final Properties properties = 
config.buildConfigProperties(instanceIndex);
+        properties.put("admin.enableServer", "false");
+
+        final Path dataDir = Paths.get(properties.getProperty("dataDir"));
+        zooKeeperEmbedded = ZooKeeperServerEmbedded.builder()
+                .configuration(properties)
+                .baseDir(dataDir.getParent())
+                .build();
+        log.info("Configure ZooKeeperServerEmbeddedAdapter with properties: 
{}", properties);
+    }
+
+    @Override
+    public QuorumPeerConfig getConfig() throws Exception {
+        if (configBuilder != null) {
+            return configBuilder.buildConfig(instanceIndex);
+        }
+
+        return null;
+    }
+
+    @Override
+    public void start() {
+        if (zooKeeperEmbedded == null) {
+            throw new FailedServerStartException(new 
NullPointerException("zooKeeperEmbedded"));
+        }
+
+        try {
+            zooKeeperEmbedded.start(DEFAULT_STARTUP_TIMEOUT.toMillis());
+        } catch (Exception e) {
+            throw new FailedServerStartException(e);
+        }
+    }
+
+    @Override
+    public void kill() {
+        close();
+    }
+
+    @Override
+    public void close() {
+        if (zooKeeperEmbedded != null) {
+            zooKeeperEmbedded.close();
+        }
+    }
+}
diff --git 
a/curator-test/src/test/java/org/apache/curator/test/TestTestingServer.java 
b/curator-test/src/test/java/org/apache/curator/test/TestTestingServer.java
index 1ddf960e..f16b2ac7 100644
--- a/curator-test/src/test/java/org/apache/curator/test/TestTestingServer.java
+++ b/curator-test/src/test/java/org/apache/curator/test/TestTestingServer.java
@@ -45,8 +45,7 @@ public class TestTestingServer {
       final InstanceSpec spec = new InstanceSpec(zkTmpDir, -1, -1, -1, true, 
-1, customTickMs, -1);
       final int zkTickTime;
       try (TestingServer testingServer = new TestingServer(spec, true)) {
-         TestingZooKeeperMain main = (TestingZooKeeperMain) 
testingServer.getTestingZooKeeperServer().getMain();
-         zkTickTime = main.getZkServer().getTickTime();
+         zkTickTime = 
testingServer.getTestingZooKeeperServer().getMain().getConfig().getTickTime();
       }
       assertEquals(customTickMs, zkTickTime);
    }

Reply via email to