Repository: curator
Updated Branches:
  refs/heads/CURATOR-3.0 ea36769af -> afa8f7a45


Removed usages of Javaassist and simplified how the in-memory ZK server is 
created and run. Tests should be more reliable and the testing server should 
respond faster


Project: http://git-wip-us.apache.org/repos/asf/curator/repo
Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/911f02b1
Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/911f02b1
Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/911f02b1

Branch: refs/heads/CURATOR-3.0
Commit: 911f02b15e9585e893bdd2c9bdd860fbf85bba4c
Parents: 73b05aa
Author: randgalt <randg...@apache.org>
Authored: Wed Sep 9 20:13:56 2015 -0500
Committer: randgalt <randg...@apache.org>
Committed: Wed Sep 9 20:13:56 2015 -0500

----------------------------------------------------------------------
 .../recipes/leader/ChaosMonkeyCnxnFactory.java  |  22 ++-
 curator-test/pom.xml                            |   5 -
 .../apache/curator/test/BaseClassForTests.java  |   1 +
 .../apache/curator/test/ByteCodeRewrite.java    | 131 ------------
 .../org/apache/curator/test/TestingCluster.java |   5 -
 .../org/apache/curator/test/TestingServer.java  |   5 -
 .../curator/test/TestingZooKeeperMain.java      | 197 +++++++++++--------
 pom.xml                                         |   7 -
 8 files changed, 134 insertions(+), 239 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/curator-recipes/src/test/java/org/apache/curator/framework/recipes/leader/ChaosMonkeyCnxnFactory.java
----------------------------------------------------------------------
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 1c0e50e..3aeec81 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
@@ -19,6 +19,7 @@
 
 package org.apache.curator.framework.recipes.leader;
 
+import org.apache.curator.test.TestingZooKeeperMain;
 import org.apache.zookeeper.ZooDefs;
 import org.apache.zookeeper.proto.CreateRequest;
 import org.apache.zookeeper.server.ByteBufferInputStream;
@@ -49,23 +50,20 @@ public class ChaosMonkeyCnxnFactory extends 
NIOServerCnxnFactory
     /* How long after the first error, connections are rejected */
     public static final long LOCKOUT_DURATION_MS = 6000;
 
-    public ChaosMonkeyCnxnFactory() throws IOException
-    {
-    }
-
     @Override
     public void startup(ZooKeeperServer zks) throws IOException, 
InterruptedException
     {
         super.startup(new ChaosMonkeyZookeeperServer(zks));
     }
 
-
     public static class ChaosMonkeyZookeeperServer extends ZooKeeperServer
     {
+        private final ZooKeeperServer zks;
         private long firstError = 0;
 
         public ChaosMonkeyZookeeperServer(ZooKeeperServer zks)
         {
+            this.zks = zks;
             setTxnLogFactory(zks.getTxnLogFactory());
             setTickTime(zks.getTickTime());
             setMinSessionTimeout(zks.getMinSessionTimeout());
@@ -73,6 +71,20 @@ public class ChaosMonkeyCnxnFactory extends 
NIOServerCnxnFactory
         }
 
         @Override
+        public void startup()
+        {
+            super.startup();
+            if ( zks instanceof TestingZooKeeperMain.TestZooKeeperServer )
+            {
+                ((TestingZooKeeperMain.TestZooKeeperServer)zks).noteStartup();
+            }
+            else
+            {
+                throw new RuntimeException("Unknown ZooKeeperServer: " + 
zks.getClass());
+            }
+        }
+
+        @Override
         public void submitRequest(Request si)
         {
             long remaining = firstError != 0 ? LOCKOUT_DURATION_MS - 
(System.currentTimeMillis() - firstError) : 0;

http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/curator-test/pom.xml
----------------------------------------------------------------------
diff --git a/curator-test/pom.xml b/curator-test/pom.xml
index 80eedb2..d401da5 100644
--- a/curator-test/pom.xml
+++ b/curator-test/pom.xml
@@ -41,11 +41,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.javassist</groupId>
-            <artifactId>javassist</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-math</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java
----------------------------------------------------------------------
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java 
b/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java
index 1f6503d..a3bc2b5 100644
--- a/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java
+++ b/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java
@@ -19,6 +19,7 @@
 
 package org.apache.curator.test;
 
+import org.apache.zookeeper.server.ServerCnxnFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.IInvokedMethod;

http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/curator-test/src/main/java/org/apache/curator/test/ByteCodeRewrite.java
----------------------------------------------------------------------
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/ByteCodeRewrite.java 
b/curator-test/src/main/java/org/apache/curator/test/ByteCodeRewrite.java
deleted file mode 100644
index d8a1c3a..0000000
--- a/curator-test/src/main/java/org/apache/curator/test/ByteCodeRewrite.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * 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 javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-import javassist.NotFoundException;
-import javassist.bytecode.AccessFlag;
-
-public class ByteCodeRewrite
-{
-    public static void apply()
-    {
-        // NOP - only needed so that static initializer is run
-    }
-
-    static
-    {
-        /*
-            This ugliness is necessary. There is no way to tell ZK to not 
register JMX beans. Something
-            in the shutdown of a QuorumPeer causes the state of the 
MBeanRegistry to get confused and
-            generates an assert Exception.
-         */
-        ClassPool pool = ClassPool.getDefault();
-        try
-        {
-            pool.appendClassPath(new 
javassist.LoaderClassPath(TestingCluster.class.getClassLoader()));     // re: 
https://github.com/Netflix/curator/issues/11
-
-            try
-            {
-                CtClass cc = 
pool.get("org.apache.zookeeper.server.ZooKeeperServer");
-                fixMethods(cc, "registerJMX", "unregisterJMX");
-            }
-            catch ( NotFoundException ignore )
-            {
-                // ignore
-            }
-
-            try
-            {
-                CtClass cc = 
pool.get("org.apache.zookeeper.server.quorum.LearnerZooKeeperServer");
-                fixMethods(cc, "registerJMX", "unregisterJMX");
-            }
-            catch ( NotFoundException ignore )
-            {
-                // ignore
-            }
-
-            try
-            {
-                CtClass cc = 
pool.get("org.apache.zookeeper.jmx.MBeanRegistry");
-                fixMethods(cc, "register", "unregister");
-            }
-            catch ( NotFoundException ignore )
-            {
-                // ignore
-            }
-
-            try
-            {
-                CtClass cc = 
pool.get("org.apache.zookeeper.server.ZooKeeperServerMain");
-                makeVolatile(cc);
-            }
-            catch ( NotFoundException e )
-            {
-                // ignore
-            }
-
-            try
-            {
-                CtClass cc = 
pool.get("org.apache.zookeeper.server.ServerCnxnFactory");
-                makeVolatile(cc);
-            }
-            catch ( NotFoundException e )
-            {
-                // ignore
-            }
-        }
-        catch ( Exception e )
-        {
-            e.printStackTrace();
-        }
-    }
-
-    private static void makeVolatile(CtClass cc) throws CannotCompileException
-    {
-        for ( CtField field : cc.getDeclaredFields() )
-        {
-            if ( (field.getModifiers() & (AccessFlag.ABSTRACT | 
AccessFlag.NATIVE | AccessFlag.SYNTHETIC | AccessFlag.STATIC | 
AccessFlag.FINAL)) == 0 )
-            {
-                field.setModifiers(field.getModifiers() | AccessFlag.VOLATILE);
-            }
-        }
-        cc.toClass();
-    }
-
-    private static void fixMethods(CtClass cc, String... methodNames) throws 
CannotCompileException
-    {
-        for ( CtMethod method : cc.getDeclaredMethods() )
-        {
-            for ( String methodName : methodNames )
-            {
-                if ( method.getName().equals(methodName) )
-                {
-                    method.setBody(null);
-                }
-            }
-        }
-        cc.toClass();
-    }
-}

http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
----------------------------------------------------------------------
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java 
b/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
index f6bdbd8..e2a1ae8 100644
--- a/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
+++ b/curator-test/src/main/java/org/apache/curator/test/TestingCluster.java
@@ -38,11 +38,6 @@ import java.util.Map;
  */
 public class TestingCluster implements Closeable
 {
-    static
-    {
-        ByteCodeRewrite.apply();
-    }
-
     private final List<TestingZooKeeperServer>  servers;
 
     /**

http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/curator-test/src/main/java/org/apache/curator/test/TestingServer.java
----------------------------------------------------------------------
diff --git 
a/curator-test/src/main/java/org/apache/curator/test/TestingServer.java 
b/curator-test/src/main/java/org/apache/curator/test/TestingServer.java
index 7ed8add..5228c8e 100644
--- a/curator-test/src/main/java/org/apache/curator/test/TestingServer.java
+++ b/curator-test/src/main/java/org/apache/curator/test/TestingServer.java
@@ -28,11 +28,6 @@ import java.io.IOException;
  */
 public class TestingServer implements Closeable
 {
-    static
-    {
-        ByteCodeRewrite.apply();
-    }
-
     private final TestingZooKeeperServer testingZooKeeperServer;
     private final InstanceSpec spec;
 

http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/curator-test/src/main/java/org/apache/curator/test/TestingZooKeeperMain.java
----------------------------------------------------------------------
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 3d0c341..702824a 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,24 +19,35 @@
 
 package org.apache.curator.test;
 
+import org.apache.zookeeper.jmx.MBeanRegistry;
+import org.apache.zookeeper.jmx.ZKMBeanInfo;
 import org.apache.zookeeper.server.ServerCnxnFactory;
 import org.apache.zookeeper.server.ServerConfig;
 import org.apache.zookeeper.server.ZKDatabase;
 import org.apache.zookeeper.server.ZooKeeperServer;
-import org.apache.zookeeper.server.ZooKeeperServerMain;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
 import org.apache.zookeeper.server.quorum.QuorumPeer;
 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.lang.reflect.Modifier;
 import java.nio.channels.ServerSocketChannel;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicReference;
 
-public class TestingZooKeeperMain extends ZooKeeperServerMain implements 
ZooKeeperMainFace
+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 volatile ServerCnxnFactory cnxnFactory;
+    private volatile ZooKeeperServer zkServer;
+
     static final int MAX_WAIT_MS = new Timing().milliseconds();
 
     @Override
@@ -44,15 +55,15 @@ public class TestingZooKeeperMain extends 
ZooKeeperServerMain implements ZooKeep
     {
         try
         {
-            Field cnxnFactoryField = 
ZooKeeperServerMain.class.getDeclaredField("cnxnFactory");
-            cnxnFactoryField.setAccessible(true);
-            ServerCnxnFactory cnxnFactory = 
(ServerCnxnFactory)cnxnFactoryField.get(this);
-            cnxnFactory.closeAll();
+            if ( cnxnFactory != null )
+            {
+                cnxnFactory.closeAll();
 
-            Field ssField = cnxnFactory.getClass().getDeclaredField("ss");
-            ssField.setAccessible(true);
-            ServerSocketChannel ss = 
(ServerSocketChannel)ssField.get(cnxnFactory);
-            ss.close();
+                Field ssField = cnxnFactory.getClass().getDeclaredField("ss");
+                ssField.setAccessible(true);
+                ServerSocketChannel ss = 
(ServerSocketChannel)ssField.get(cnxnFactory);
+                ss.close();
+            }
 
             close();
         }
@@ -65,12 +76,36 @@ public class TestingZooKeeperMain extends 
ZooKeeperServerMain implements ZooKeep
     @Override
     public void runFromConfig(QuorumPeerConfig config) throws Exception
     {
+        try
+        {
+            Field instance = MBeanRegistry.class.getDeclaredField("instance");
+            instance.setAccessible(true);
+            MBeanRegistry nopMBeanRegistry = new MBeanRegistry()
+            {
+                @Override
+                public void register(ZKMBeanInfo bean, ZKMBeanInfo parent) 
throws JMException
+                {
+                    // NOP
+                }
+
+                @Override
+                public void unregister(ZKMBeanInfo bean)
+                {
+                    // NOP
+                }
+            };
+            instance.set(null, nopMBeanRegistry);
+        }
+        catch ( Exception e )
+        {
+            log.error("Could not fix MBeanRegistry");
+        }
+
         ServerConfig serverConfig = new ServerConfig();
         serverConfig.readFrom(config);
-        latch.countDown();
         try
         {
-            super.runFromConfig(serverConfig);
+            internalRunFromConfig(serverConfig);
         }
         catch ( IOException e )
         {
@@ -91,28 +126,20 @@ public class TestingZooKeeperMain extends 
ZooKeeperServerMain implements ZooKeep
     {
         latch.await();
 
-        ServerCnxnFactory cnxnFactory = getServerConnectionFactory();
-        if ( cnxnFactory != null )
+        if ( zkServer != null )
         {
-            final ZooKeeperServer zkServer = getZooKeeperServer(cnxnFactory);
-            if ( zkServer != null )
+            //noinspection SynchronizeOnNonFinalField
+            synchronized(zkServer)
             {
-                synchronized(zkServer)
+                while ( !zkServer.isRunning() )
                 {
-                    if ( !zkServer.isRunning() )
-                    {
-                        zkServer.wait();
-                    }
+                    zkServer.wait();
                 }
             }
-            else
-            {
-                throw new Exception("No zkServer");
-            }
         }
         else
         {
-            throw new Exception("No connection factory");
+            throw new Exception("No zkServer. zkServer is volatile: " + 
Modifier.isVolatile(cnxnFactory.getClass().getDeclaredField("zkServer").getModifiers()));
         }
 
         Exception exception = startingException.get();
@@ -127,27 +154,27 @@ public class TestingZooKeeperMain extends 
ZooKeeperServerMain implements ZooKeep
     {
         try
         {
-            shutdown();
+            cnxnFactory.shutdown();
         }
         catch ( Throwable e )
         {
             e.printStackTrace();    // just ignore - this class is only for 
testing
         }
+        finally
+        {
+            cnxnFactory = null;
+        }
 
         try
         {
-            ServerCnxnFactory cnxnFactory = getServerConnectionFactory();
-            if ( cnxnFactory != null )
+            if ( zkServer != null )
             {
-                ZooKeeperServer zkServer = getZooKeeperServer(cnxnFactory);
-                if ( zkServer != null )
+                zkServer.shutdown();
+                ZKDatabase zkDb = zkServer.getZKDatabase();
+                if ( zkDb != null )
                 {
-                    ZKDatabase zkDb = zkServer.getZKDatabase();
-                    if ( zkDb != null )
-                    {
-                        // make ZK server close its log files
-                        zkDb.close();
-                    }
+                    // make ZK server close its log files
+                    zkDb.close();
                 }
             }
         }
@@ -155,61 +182,69 @@ public class TestingZooKeeperMain extends 
ZooKeeperServerMain implements ZooKeep
         {
             e.printStackTrace();    // just ignore - this class is only for 
testing
         }
+        finally
+        {
+            zkServer = null;
+        }
     }
 
-    private ServerCnxnFactory getServerConnectionFactory() throws Exception
+    // copied from ZooKeeperServerMain.java
+    private void internalRunFromConfig(ServerConfig config) throws IOException
     {
-        Field cnxnFactoryField = 
ZooKeeperServerMain.class.getDeclaredField("cnxnFactory");
-        cnxnFactoryField.setAccessible(true);
-        ServerCnxnFactory cnxnFactory;
-
-        // Wait until the cnxnFactory field is non-null or up to 1s, whichever 
comes first.
-        long startTime = System.currentTimeMillis();
-        do
-        {
-            cnxnFactory = (ServerCnxnFactory)cnxnFactoryField.get(this);
-            if ( cnxnFactory == null )
-            {
-                try
-                {
-                    Thread.sleep(10);
-                }
-                catch ( InterruptedException e )
-                {
-                    Thread.currentThread().interrupt();
-                    throw e;
-                }
+        log.info("Starting server");
+        FileTxnSnapLog txnLog = null;
+        try {
+            // Note that this thread isn't going to be doing anything else,
+            // so rather than spawning another thread, we will just call
+            // run() in this thread.
+            // create a file logger url from the command line args
+            txnLog = new FileTxnSnapLog(config.getDataLogDir(), 
config.getDataDir());
+            zkServer = new TestZooKeeperServer(txnLog, config);
+
+            cnxnFactory = ServerCnxnFactory.createFactory();
+            cnxnFactory.configure(config.getClientPortAddress(),
+                config.getMaxClientCnxns());
+            cnxnFactory.startup(zkServer);
+            latch.countDown();
+            cnxnFactory.join();
+            if ( zkServer.isRunning()) {
+                zkServer.shutdown();
+            }
+        } catch (InterruptedException e) {
+            // warn, but generally this is ok
+            Thread.currentThread().interrupt();
+            log.warn("Server interrupted", e);
+        } finally {
+            if (txnLog != null) {
+                txnLog.close();
             }
         }
-        while ( (cnxnFactory == null) && ((System.currentTimeMillis() - 
startTime) <= MAX_WAIT_MS) );
-
-        return cnxnFactory;
     }
 
-    private ZooKeeperServer getZooKeeperServer(ServerCnxnFactory cnxnFactory) 
throws Exception
+    public static class TestZooKeeperServer extends ZooKeeperServer
     {
-        ZooKeeperServer zkServer;
+        public TestZooKeeperServer(FileTxnSnapLog txnLog, ServerConfig config)
+        {
+            super(txnLog, config.getTickTime(), config.getMinSessionTimeout(), 
config.getMaxSessionTimeout(), null);
+        }
 
-        // Wait until the zkServer field is non-null
-        long startTime = System.currentTimeMillis();
-        do
+        protected void registerJMX()
         {
-            zkServer = cnxnFactory.getZooKeeperServer();
-            if ( zkServer == null )
-            {
-                try
-                {
-                    Thread.sleep(10);
-                }
-                catch ( InterruptedException e )
-                {
-                    Thread.currentThread().interrupt();
-                    throw e;
-                }
-            }
+            // NOP
         }
-        while ( (zkServer == null) && ((System.currentTimeMillis() - 
startTime) <= MAX_WAIT_MS) );
 
-        return zkServer;
+        @Override
+        protected void unregisterJMX()
+        {
+            // NOP
+        }
+
+        public void noteStartup()
+        {
+            synchronized (this) {
+                running = true;
+                notifyAll();
+            }
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/curator/blob/911f02b1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b48ff54..59ed3e0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,7 +65,6 @@
         <maven-javadoc-plugin-version>2.10.3</maven-javadoc-plugin-version>
         <doxia-module-confluence-version>1.6</doxia-module-confluence-version>
         <maven-license-plugin-version>1.9.0</maven-license-plugin-version>
-        <javassist-version>3.18.1-GA</javassist-version>
         <commons-math-version>2.2</commons-math-version>
         <jackson-mapper-asl-version>1.9.13</jackson-mapper-asl-version>
         <jersey-version>1.18.1</jersey-version>
@@ -346,12 +345,6 @@
             </dependency>
 
             <dependency>
-                <groupId>org.javassist</groupId>
-                <artifactId>javassist</artifactId>
-                <version>${javassist-version}</version>
-            </dependency>
-
-            <dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-math</artifactId>
                 <version>${commons-math-version}</version>

Reply via email to