activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jstrac...@apache.org
Subject svn commit: r679308 - in /activemq/sandbox/zookeeper: ./ zookeeper-core/ zookeeper-protocols/ zookeeper-protocols/src/ zookeeper-protocols/src/main/ zookeeper-protocols/src/main/java/ zookeeper-protocols/src/main/java/org/ zookeeper-protocols/src/main/...
Date Thu, 24 Jul 2008 08:50:01 GMT
Author: jstrachan
Date: Thu Jul 24 01:49:59 2008
New Revision: 679308

URL: http://svn.apache.org/viewvc?rev=679308&view=rev
Log:
added the patch for https://issues.apache.org/jira/browse/ZOOKEEPER-78 to implement a WriteLock high level protocol; though this patch has been modified to fit into the maven directory structure and it creates a separate zookeeper-protocols.jar which contains the higher level protocol and utilities including ZooKeeperFacade for dealing with reconnections with new sessions if a session expires and ProtocolSupport for retrying operations or blocks of synchronous code when there is a connection failure or session timeout exception

Added:
    activemq/sandbox/zookeeper/zookeeper-protocols/
    activemq/sandbox/zookeeper/zookeeper-protocols/pom.xml   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ProtocolSupport.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/WriteLock.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZNodeName.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperFacade.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperOperation.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/doc-files/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/doc-files/writeLockProtocol.html   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/main/resources/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/WriteLockTest.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZNodeNameTest.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZooKeeperTestSupport.java   (with props)
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/resources/
    activemq/sandbox/zookeeper/zookeeper-protocols/src/test/resources/log4j.properties   (with props)
Modified:
    activemq/sandbox/zookeeper/pom.xml
    activemq/sandbox/zookeeper/zookeeper-core/pom.xml

Modified: activemq/sandbox/zookeeper/pom.xml
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/pom.xml?rev=679308&r1=679307&r2=679308&view=diff
==============================================================================
--- activemq/sandbox/zookeeper/pom.xml (original)
+++ activemq/sandbox/zookeeper/pom.xml Thu Jul 24 01:49:59 2008
@@ -69,6 +69,7 @@
     <module>zookeeper-jute-compiler</module>
     <module>zookeeper-core</module>
     <module>zookeeper-jmx</module>
+    <module>zookeeper-protocols</module>
     <module>zookeeper-all</module>
     <module>zookeeper-c</module>
   </modules>

Modified: activemq/sandbox/zookeeper/zookeeper-core/pom.xml
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-core/pom.xml?rev=679308&r1=679307&r2=679308&view=diff
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-core/pom.xml (original)
+++ activemq/sandbox/zookeeper/zookeeper-core/pom.xml Thu Jul 24 01:49:59 2008
@@ -40,9 +40,12 @@
       <groupId>log4j</groupId>
       <artifactId>log4j</artifactId>
     </dependency>
+
+    <!-- testing dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
+      <scope>test</scope>
     </dependency>
   </dependencies>
 

Added: activemq/sandbox/zookeeper/zookeeper-protocols/pom.xml
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/pom.xml?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/pom.xml (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/pom.xml Thu Jul 24 01:49:59 2008
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.zookeeper</groupId>
+    <artifactId>zookeeper-pom</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.apache.zookeeper</groupId>
+  <artifactId>zookeeper-protocols</artifactId>
+  <version>3.0.0-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+  <name>ZooKeeper :: Protocols</name>
+  <description>A collection of higher level protocols for things like Write Lock and Leader Election and helper classes for working with the ZooKeeper client</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.zookeeper</groupId>
+      <artifactId>zookeeper-jute</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.zookeeper</groupId>
+      <artifactId>zookeeper-core</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.apache.zookeeper</groupId>
+      <artifactId>zookeeper-jmx</artifactId>
+    </dependency>
+
+    <!-- testing dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      
+      <plugin>
+        <groupId>org.apache.geronimo.genesis.plugins</groupId>
+        <artifactId>tools-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>verify-legal-files</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>verify-legal-files</goal>
+            </goals>
+            <configuration>
+              <strict>false</strict>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+            
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ProtocolSupport.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ProtocolSupport.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ProtocolSupport.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ProtocolSupport.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,180 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.io.IOException;
+
+/**
+ * A base class for protocol implementations which provides a number of higher level helper methods
+ * for working with ZooKeeper along with retrying synchronous operations if the connection to ZooKeeper
+ * closes such as {@link #retryOperation(ZooKeeperOperation)}
+ *
+ * @version $Revision: 1.1 $
+ */
+public class ProtocolSupport {
+    private static final Logger LOG = Logger.getLogger(ProtocolSupport.class);
+
+    protected final ZooKeeperFacade zookeeper;
+    private AtomicBoolean closed = new AtomicBoolean(false);
+    private long retryDelay = 500L;
+    private int retryCount = 10;
+    private List<ACL> acl = ZooDefs.Ids.OPEN_ACL_UNSAFE;
+
+    public ProtocolSupport(ZooKeeperFacade zookeeper) {
+        this.zookeeper = zookeeper;
+    }
+
+    /**
+     * Closes this strategy and releases any ZooKeeper resources; but keeps the ZooKeeper instance open
+     */
+    public void close() {
+        if (closed.compareAndSet(false, true)) {
+            doClose();
+        }
+    }
+
+    public ZooKeeperFacade getZookeeper() {
+        return zookeeper;
+    }
+
+    public List<ACL> getAcl() {
+        return acl;
+    }
+
+    public void setAcl(List<ACL> acl) {
+        this.acl = acl;
+    }
+
+    public long getRetryDelay() {
+        return retryDelay;
+    }
+
+    /**
+     * Sets the time waited between retry delays
+     *
+     * @param retryDelay
+     */
+    public void setRetryDelay(long retryDelay) {
+        this.retryDelay = retryDelay;
+    }
+
+    // Implementation methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Allow derived classes to perform some custom closing operations to release resources
+     */
+    protected void doClose() {
+    }
+
+
+    /**
+     * Perform the given operation, retrying if the connection fails
+     */
+    protected Object retryOperation(ZooKeeperOperation operation) throws KeeperException, InterruptedException {
+        KeeperException exception = null;
+        for (int i = 0; i < retryCount; i++) {
+            try {
+                return operation.execute();
+            } catch (KeeperException.SessionExpiredException e) {
+                LOG.warn("Session expired for: " + zookeeper + " so reconnecting due to: " + e, e);
+
+                try {
+                    zookeeper.reconnectWithNewSession();
+                } catch (IOException e1) {
+                    LOG.warn("Failed to disconnect after a session expired: " + e, e);
+                }
+            } catch (KeeperException.ConnectionLossException e) {
+                if (exception == null) {
+                    exception = e;
+                }
+                LOG.info("Attempt " + i + " failed with connection loss so attempting to reconnect: " + e, e);
+                retryDelay(i);
+            }
+        }
+        throw exception;
+    }
+
+    /**
+     * Ensures that the given path exists with no data, the current
+     * ACL and no flags
+     *
+     * @param path
+     */
+    protected void ensurePathExists(String path) {
+        ensureExists(path, null, acl, 0);
+    }
+
+    /**
+     * Ensures that the given path exists with the given data, ACL and flags
+     *
+     * @param path
+     * @param acl
+     * @param flags
+     */
+    protected void ensureExists(final String path, final byte[] data, final List<ACL> acl, final int flags) {
+        try {
+            retryOperation(new ZooKeeperOperation() {
+                public Object execute() throws KeeperException, InterruptedException {
+                    Stat stat = zookeeper.exists(path, false);
+                    if (stat != null) {
+                        return null;
+                    }
+                    return zookeeper.create(path, data, acl, flags);
+                }
+            });
+        } catch (KeeperException e) {
+            LOG.warn("Caught: " + e, e);
+        } catch (InterruptedException e) {
+            LOG.warn("Caught: " + e, e);
+        }
+    }
+
+    /**
+     * Returns true if this protocol has been closed
+     *
+     * @return true if this protocol is closed
+     */
+    protected boolean isClosed() {
+        return closed.get();
+    }
+
+    /**
+     * Performs a retry delay if this is not the first attempt
+     *
+     * @param attemptCount the number of the attempts performed so far
+     */
+    protected void retryDelay(int attemptCount) {
+        if (attemptCount > 0) {
+            try {
+                Thread.sleep(attemptCount * retryDelay);
+            } catch (InterruptedException e) {
+                LOG.debug("Failed to sleep: " + e, e);
+            }
+        }
+    }
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ProtocolSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/WriteLock.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/WriteLock.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/WriteLock.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/WriteLock.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,226 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Watcher;
+import static org.apache.zookeeper.ZooDefs.CreateFlags.EPHEMERAL;
+import static org.apache.zookeeper.ZooDefs.CreateFlags.SEQUENCE;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.proto.WatcherEvent;
+
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * A <a href="doc-files/writeLockProtocol.html">protocol to implement an exclusive write lock or to elect a leader</a>.
+ * <p/>
+ * You invoke {@link #acquire()} to start the process of grabbing the lock; you may get the lock then or it may be some time later.
+ * <p/>
+ * You can register a Runnable so that you are invoked when you get the lock; otherwise you can ask if you have the lock
+ * by calling {@link #isOwner()}
+ *
+ * @version $Revision: 1.1 $
+ */
+public class WriteLock extends ProtocolSupport {
+    private static final Logger LOG = Logger.getLogger(WriteLock.class);
+
+    private final String dir;
+    private String id;
+    private ZNodeName idName;
+    private String ownerId;
+    private String lastChildId;
+    private byte[] data = {0x12, 0x34};
+    private Runnable whenOwner;
+
+    public WriteLock(ZooKeeperFacade zookeeper, String dir) {
+        super(zookeeper);
+        this.dir = dir;
+    }
+
+
+    /**
+     * Removes the lock or associated znode if you no longer require the lock
+     */
+    public void unlock() {
+        if (!isClosed() && id != null) {
+            // we don't need to retry this operation in the case of failure
+            // as ZK will remove ephemeral files and we don't wanna hang
+            // this process when closing if we cannot reconnect to ZK
+            try {
+                if (zookeeper.exists(id, false) != null) {
+                    zookeeper.delete(id, -1);
+                }
+            } catch (InterruptedException e) {
+                LOG.warn("Caught: " + e, e);
+            } catch (KeeperException e) {
+                LOG.warn("Caught: " + e, e);
+            }
+            finally {
+                id = null;
+            }
+        }
+    }
+
+    /**
+     * Attempts to acquire the exclusive write lock returning whether or not it was acquired.
+     * Note that the exclusive lock may be acquired some time later after this method has been invoked
+     * due to the current lock owner going away.
+     */
+    public boolean acquire() throws KeeperException, InterruptedException {
+        if (isClosed()) {
+            return false;
+        }
+        ensurePathExists(dir);
+
+        return (Boolean) retryOperation(new ZooKeeperOperation() {
+            public Object execute() throws KeeperException, InterruptedException {
+                do {
+                    if (id == null) {
+                        long sessionId = zookeeper.getSessionId();
+                        String prefix = "x-" + sessionId + "-";
+
+                        // lets try look up the current ID if we failed in the middle of creating the znode
+                        List<String> names = zookeeper.getChildren(dir, false);
+                        for (String name : names) {
+                            if (name.startsWith(prefix)) {
+                                id = name;
+                                if (LOG.isDebugEnabled()) {
+                                    LOG.debug("Found id created last time: " + id);
+                                }
+                                break;
+                            }
+                        }
+                        if (id == null) {
+                            id = zookeeper.create(dir + "/" + prefix, data, getAcl(), EPHEMERAL | SEQUENCE);
+
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("Created id: " + id);
+                            }
+                        }
+                        idName = new ZNodeName(id);
+                    }
+                    if (id != null) {
+                        List<String> names = zookeeper.getChildren(dir, false);
+                        if (names.isEmpty()) {
+                            LOG.warn("No children in: " + dir + " when we've just created one! Lets recreate it...");
+                            // lets force the recreation of the id
+                            id = null;
+                        } else {
+                            // lets sort them explicitly (though they do seem to come back in order ususally :)
+                            SortedSet<ZNodeName> sortedNames = new TreeSet<ZNodeName>();
+                            for (String name : names) {
+                                sortedNames.add(new ZNodeName(dir + "/" + name));
+                            }
+                            ownerId = sortedNames.first().getName();
+
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug(dir + " has names: " + sortedNames);
+                            }
+
+                            SortedSet<ZNodeName> lessThanMe = sortedNames.headSet(idName);
+                            if (!lessThanMe.isEmpty()) {
+                                ZNodeName lastChildName = lessThanMe.last();
+                                lastChildId = lastChildName.getName();
+
+                                if (LOG.isDebugEnabled()) {
+                                    LOG.debug("watching less than me node: " + lastChildId);
+                                }
+
+
+                                Stat stat = zookeeper.exists(lastChildId, new Watcher() {
+                                    public void process(WatcherEvent event) {
+                                        // lets either become the leader or watch the new/updated node
+                                        LOG.debug("Watcher fired on path: " + event.getPath() + " state: " + event.getState() + " type " + event.getType());
+                                        try {
+                                            acquire();
+                                        } catch (KeeperException e) {
+                                            LOG.warn("Failed to acquire lock: " + e, e);
+                                        } catch (InterruptedException e) {
+                                            LOG.warn("Failed to acquire lock: " + e, e);
+                                        }
+                                    }
+                                });
+                                if (stat != null) {
+                                    return Boolean.FALSE;
+                                } else {
+                                    LOG.warn("Could not find the stats for less than me: " + lastChildName.getName());
+                                }
+                            } else {
+                                if (isOwner()) {
+                                    if (whenOwner != null) {
+                                        whenOwner.run();
+                                    }
+                                    return Boolean.TRUE;
+                                }
+                            }
+                        }
+                    }
+                }
+                while (id == null);
+                return Boolean.FALSE;
+            }
+        });
+    }
+
+    public String getDir() {
+        return dir;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getOwnerId() {
+        return ownerId;
+    }
+
+    public String getLastChildId() {
+        return lastChildId;
+    }
+
+    /**
+     * Returns true if this node is the owner of the lock (or the leader)
+     */
+    public boolean isOwner() {
+        return id != null && ownerId != null && id.equals(ownerId);
+    }
+
+    public Runnable getWhenOwner() {
+        return whenOwner;
+    }
+
+    /**
+     * Allows a runnable to be associated when this node becomes the owner of the lock
+     */
+    public void setWhenOwner(Runnable whenOwner) {
+        this.whenOwner = whenOwner;
+    }
+
+    // Implementation methods
+    //-------------------------------------------------------------------------
+
+    @Override
+    protected void doClose() {
+        unlock();
+    }
+
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/WriteLock.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZNodeName.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZNodeName.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZNodeName.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZNodeName.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,105 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+/**
+ * Represents an ephemeral znode name which has an ordered sequence number
+ * and can be sorted in order
+ *
+ * @version $Revision: 1.1 $
+ */
+public class ZNodeName implements Comparable<ZNodeName> {
+    private final String name;
+    private String prefix;
+    private int sequence = -1;
+
+    public ZNodeName(String name) {
+        if (name == null) {
+            throw new NullPointerException("id cannot be null");
+        }
+        this.name = name;
+        this.prefix = name;
+        int idx = name.lastIndexOf('-');
+        if (idx >= 0) {
+            this.prefix = name.substring(0, idx);
+            try {
+                this.sequence = Integer.parseInt(name.substring(idx + 1));
+                // If an exception occurred we misdetected a sequence suffix,
+                // so return -1.
+            } catch (NumberFormatException e) {
+            } catch (ArrayIndexOutOfBoundsException e) {
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return name.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ZNodeName sequence = (ZNodeName) o;
+
+        if (!name.equals(sequence.name)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode() + 37;
+    }
+
+    public int compareTo(ZNodeName that) {
+        int answer = this.prefix.compareTo(that.prefix);
+        if (answer == 0) {
+            int s1 = this.sequence;
+            int s2 = that.sequence;
+            if (s1 == -1 && s2 == -1) {
+                return this.name.compareTo(that.name);
+            }
+            answer = s1 == -1 ? 1 : s2 == -1 ? -1 : s1 - s2;
+        }
+        return answer;
+    }
+
+    /**
+     * Returns the name of the znode
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the sequence number
+     */
+    public int getZNodeName() {
+        return sequence;
+    }
+
+    /**
+     * Returns the text prefix before the sequence number
+     */
+    public String getPrefix() {
+        return prefix;
+    }
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZNodeName.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperFacade.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperFacade.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperFacade.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperFacade.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,245 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.proto.WatcherEvent;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * A facade around the {@link ZooKeeper} instance which can deal with sessions expiring so that the facade is capable
+ * of reconnecting to the ZooKeeper server via the {@link #reconnectWithNewSession()} method.
+ *
+ * @version $Revision: 1.1 $
+ */
+public class ZooKeeperFacade {
+    private ZooKeeper zookeeper;
+    private final String host;
+    private final int sessionTimeout;
+    private volatile Watcher defaultWatcher;
+    private long sessionId;
+    private byte[] sessionPasswd;
+
+    public ZooKeeperFacade(String host, int sessionTimeout, Watcher watcher) throws IOException {
+        this.host = host;
+        this.sessionTimeout = sessionTimeout;
+        this.defaultWatcher = watcher;
+        zookeeper = createZooKeeper();
+    }
+
+    public ZooKeeperFacade(String host, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd) throws IOException {
+        this.host = host;
+        this.sessionTimeout = sessionTimeout;
+        this.defaultWatcher = watcher;
+        this.sessionId = sessionId;
+        this.sessionPasswd = sessionPasswd;
+        zookeeper = createZooKeeper();
+    }
+
+    /**
+     * Returns the {@link ZooKeeper} instance which can be recreated under your feet if a session expires and
+     * a call is made to {@link #reconnectWithNewSession()} 
+     */
+    public synchronized ZooKeeper getZookeeper() {
+        return zookeeper;
+    }
+
+    public void setZookeeper(ZooKeeper zookeeper) {
+        this.zookeeper = zookeeper;
+    }
+
+    /**
+     * Forces reconnection to the ZooKeeper server with a new session ID.
+     * This method should only be called after the session has expired (which should be rare!)
+     * as the TCP connection will be closed and all ephemeral files deleted!
+     *
+     * @throws InterruptedException
+     * @throws IOException
+     */
+    public void reconnectWithNewSession() throws InterruptedException, IOException {
+        close();
+
+        // now lets force the reconnection
+        sessionId = 0;
+        zookeeper = createZooKeeper();
+    }
+
+
+    // Delegate methods
+    //-------------------------------------------------------------------------
+    public void addAuthInfo(String scheme, byte[] auth) throws IOException {
+        getZookeeper().addAuthInfo(scheme, auth);
+    }
+
+    public void close() throws InterruptedException {
+        if (zookeeper != null) {
+            try {
+                zookeeper.close();
+            } finally {
+                zookeeper = null;
+            }
+        }
+    }
+
+    public String create(String path, byte[] data, List<ACL> acl, int flags) throws KeeperException, InterruptedException {
+        return getZookeeper().create(path, data, acl, flags);
+    }
+
+    public void create(String path, byte[] data, List<ACL> acl, int flags, AsyncCallback.StringCallback cb, Object ctx) {
+        getZookeeper().create(path, data, acl, flags, cb, ctx);
+    }
+
+    public void delete(String path, int version) throws InterruptedException, KeeperException {
+        getZookeeper().delete(path, version);
+    }
+
+    public void delete(String path, int version, AsyncCallback.VoidCallback cb, Object ctx) {
+        getZookeeper().delete(path, version, cb, ctx);
+    }
+
+    public String describeCNXN() {
+        return getZookeeper().describeCNXN();
+    }
+
+    public void disconnect() throws IOException {
+        getZookeeper().disconnect();
+    }
+
+    public Stat exists(String path, boolean watch) throws KeeperException, InterruptedException {
+        return getZookeeper().exists(path, watch);
+    }
+
+    public void exists(String path, boolean watch, AsyncCallback.StatCallback cb, Object ctx) {
+        getZookeeper().exists(path, watch, cb, ctx);
+    }
+
+    public Stat exists(String path, Watcher watcher) throws KeeperException, InterruptedException {
+        return getZookeeper().exists(path, watcher);
+    }
+
+    public void exists(String path, Watcher watcher, AsyncCallback.StatCallback cb, Object ctx) {
+        getZookeeper().exists(path, watcher, cb, ctx);
+    }
+
+    public List<ACL> getACL(String path, Stat stat) throws KeeperException, InterruptedException {
+        return getZookeeper().getACL(path, stat);
+    }
+
+    public void getACL(String path, Stat stat, AsyncCallback.ACLCallback cb, Object ctx) {
+        getZookeeper().getACL(path, stat, cb, ctx);
+    }
+
+    public List<String> getChildren(String path, boolean watch) throws KeeperException, InterruptedException {
+        return getZookeeper().getChildren(path, watch);
+    }
+
+    public void getChildren(String path, boolean watch, AsyncCallback.ChildrenCallback cb, Object ctx) {
+        getZookeeper().getChildren(path, watch, cb, ctx);
+    }
+
+    public List<String> getChildren(String path, Watcher watcher) throws KeeperException, InterruptedException {
+        return getZookeeper().getChildren(path, watcher);
+    }
+
+    public void getChildren(String path, Watcher watcher, AsyncCallback.ChildrenCallback cb, Object ctx) {
+        getZookeeper().getChildren(path, watcher, cb, ctx);
+    }
+
+    public void getData(String path, boolean watch, AsyncCallback.DataCallback cb, Object ctx) {
+        getZookeeper().getData(path, watch, cb, ctx);
+    }
+
+    public byte[] getData(String path, boolean watch, Stat stat) throws KeeperException, InterruptedException {
+        return getZookeeper().getData(path, watch, stat);
+    }
+
+    public void getData(String path, Watcher watcher, AsyncCallback.DataCallback cb, Object ctx) {
+        getZookeeper().getData(path, watcher, cb, ctx);
+    }
+
+    public byte[] getData(String path, Watcher watcher, Stat stat) throws KeeperException, InterruptedException {
+        return getZookeeper().getData(path, watcher, stat);
+    }
+
+    public long getSessionId() {
+        return getZookeeper().getSessionId();
+    }
+
+    public byte[] getSessionPasswd() {
+        return getZookeeper().getSessionPasswd();
+    }
+
+    public ZooKeeper.States getState() {
+        return getZookeeper().getState();
+    }
+
+    public void main(String[] args) throws NumberFormatException, KeeperException, IOException, InterruptedException {
+        getZookeeper().main(args);
+    }
+
+    public void processWatchEvent(WatcherEvent event) {
+        getZookeeper().processWatchEvent(event);
+    }
+
+    public void register(Watcher watcher) {
+        getZookeeper().register(watcher);
+    }
+
+    public Stat setACL(String path, List<ACL> acl, int version) throws KeeperException, InterruptedException {
+        return getZookeeper().setACL(path, acl, version);
+    }
+
+    public void setACL(String path, List<ACL> acl, int version, AsyncCallback.StatCallback cb, Object ctx) {
+        getZookeeper().setACL(path, acl, version, cb, ctx);
+    }
+
+    public Stat setData(String path, byte[] data, int version) throws KeeperException, InterruptedException {
+        return getZookeeper().setData(path, data, version);
+    }
+
+    public void setData(String path, byte[] data, int version, AsyncCallback.StatCallback cb, Object ctx) {
+        getZookeeper().setData(path, data, version, cb, ctx);
+    }
+
+    public void sync(String path, AsyncCallback.VoidCallback cb, Object ctx) {
+        getZookeeper().sync(path, cb, ctx);
+    }
+
+    public String toString() {
+        return getZookeeper().toString();
+    }
+    
+    // Implementation methods
+    //-------------------------------------------------------------------------
+
+    protected ZooKeeper createZooKeeper() throws IOException {
+        if (sessionId != 0 || sessionPasswd != null) {
+            return new ZooKeeper(host, sessionTimeout, defaultWatcher, sessionId, sessionPasswd);
+        }
+        else {
+            return new ZooKeeper(host, sessionTimeout, defaultWatcher);
+        }
+    }
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperFacade.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperOperation.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperOperation.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperOperation.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperOperation.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,38 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * A callback object which can be used for implementing retry-able operations in the {@link org.apache.zookeeper.protocols.ProtocolSupport} class
+ *
+ * @version $Revision: 1.1 $
+ */
+public interface ZooKeeperOperation {
+    
+    /**
+     * Performs the operation - which may be involved multiple times if the connection
+     * to ZooKeeper closes during this operation
+     *
+     * @return the result of the operation or null
+     * @throws KeeperException
+     * @throws InterruptedException
+     */
+    public Object execute() throws KeeperException, InterruptedException;
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/ZooKeeperOperation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/doc-files/writeLockProtocol.html
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/doc-files/writeLockProtocol.html?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/doc-files/writeLockProtocol.html (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/doc-files/writeLockProtocol.html Thu Jul 24 01:49:59 2008
@@ -0,0 +1,65 @@
+<html>
+<body>
+<h1>Write Lock Protocol</h1>
+
+<p>
+  The protocol devised by Runping Qi implements exclusive write locks; it can also be used for Leader Election where
+  owning the lock is equivalent to being the leader.
+</p>
+
+<p>
+  In pseudocode the algorithm is as follows; where each znode watches the previous znode to avoid the herd effect.
+</p>
+
+<ol>
+  <li>
+    id = create(".../locks/x-", SEQUENCE | EPHEMERAL)
+  </li>
+  <li>
+    getChildren(Ò.../locks"/, false)
+  </li>
+  <li>
+    sort the children in number order
+    if id is the 1st child, exit - you have the lock
+  </li>
+  <li>
+    exists(name of last child before id, true) to detect if the znode before you goes away
+  </li>
+  <li>
+    if does not exist, goto 2)
+  </li>
+  <li>
+    wait for event
+  </li>
+  <li>
+    goto 2)
+  </li>
+</ol>
+
+<p>
+  First of all, when you create child nodes of the node that holds the leadership bids,
+  you must create them with the EPHEMERAL and SEQUENCE flag.
+  ZooKeeper guarantees to give you an ephemeral node named uniquely and with a sequence number larger by at least one
+  than any previously created node in the sequence.
+  You provide a prefix, like "L_" or your own choice, and ZooKeeper creates nodes named "L_23", "L_24", etc.
+  The sequence number starts at 0 and increases monotonously.
+</p>
+
+<p>
+  Once you've placed your leadership bid, you search backwards from the sequence number of *your* node to see if there
+  are any preceding (in terms of the sequence number) nodes.
+  When you find one, you place a watch on it and wait for it to disappear.
+  When you get the watch notification, you search again, until you do not find a preceding node, then you know you're
+  the leader.
+</p>
+
+<p>
+  This protocol guarantees that there is at any time only one node that thinks it is the leader.
+  But it does not disseminate information about who is the leader. If you want everyone to know who is the leader,
+  you can have an additional Znode whose value is the name of the current leader
+  (or some identifying information on how to contact the leader, etc.).
+  Note that this cannot be done atomically, so by the time other nodes find out who the leader is,
+  the leadership may already have passed on to a different node.
+</p>
+</body>
+</html>
\ No newline at end of file

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/main/java/org/apache/zookeeper/protocols/doc-files/writeLockProtocol.html
------------------------------------------------------------------------------
    svn:mime-type = text/html

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/WriteLockTest.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/WriteLockTest.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/WriteLockTest.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/WriteLockTest.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,158 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.proto.WatcherEvent;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class WriteLockTest extends ZooKeeperTestSupport {
+    private static final Logger LOG = Logger.getLogger(WriteLockTest.class);
+
+    protected int sessionTimeout = 10 * 1000;
+    protected String dir = "/" + getClass().getName();
+    protected WriteLock[] nodes;
+    protected CountDownLatch latch = new CountDownLatch(1);
+    private boolean restartServer = true;
+
+    // TODO set this value to false when the patch for ZOOKEEPER-63 is applied!
+    private boolean workAroundClosingLastZNodeFails = true;
+    private boolean killLeader = true;
+
+    public void testRun() throws Exception {
+        runTest(3);
+    }
+
+    protected void runTest(int count) throws Exception {
+        nodes = new WriteLock[count];
+        for (int i = 0; i < count; i++) {
+            final int nodeId = i;
+            ZooKeeperFacade keeper = new ZooKeeperFacade("127.0.0.1:2181", sessionTimeout, new Watcher() {
+                public void process(WatcherEvent event) {
+                    LOG.info("ZooKeeper Event for znode: " + nodeId + " on path: " + event.getPath() + " state: " + event.getState() + " type: " + event.getType());
+                }
+            });
+            WriteLock leader = new WriteLock(keeper, dir);
+            leader.setWhenOwner(new Runnable() {
+                public void run() {
+                    latch.countDown();
+                }
+            });
+            nodes[i] = leader;
+
+            leader.acquire();
+        }
+
+        // lets wait for any previous leaders to die and one of our new
+        // nodes to become the new leader
+        latch.await(30, TimeUnit.SECONDS);
+
+        WriteLock first = nodes[0];
+        dumpNodes(count);
+
+        // lets assert that the first election is the leader
+        assertTrue("The first znode should be the leader " + first.getId(), first.isOwner());
+
+        for (int i = 1; i < count; i++) {
+            WriteLock node = nodes[i];
+            assertFalse("Node should not be the leader " + node.getId(), node.isOwner());
+        }
+
+        if (count > 1) {
+            if (killLeader) {
+            System.out.println("Now killing the leader");
+            // now lets kill the leader
+            latch = new CountDownLatch(1);
+            first.unlock();
+            latch.await(30, TimeUnit.SECONDS);
+
+            //Thread.sleep(10000);
+            WriteLock second = nodes[1];
+
+            dumpNodes(count);
+
+            // lets assert that the first election is the leader
+            assertTrue("The second znode should be the leader " + second.getId(), second.isOwner());
+
+            for (int i = 2; i < count; i++) {
+                WriteLock node = nodes[i];
+                assertFalse("Node should not be the leader " + node.getId(), node.isOwner());
+            }
+            }
+
+
+            if (restartServer) {
+                // now lets stop the server
+                System.out.println("Now stopping the server");
+                stopServer();
+                Thread.sleep(10000);
+
+                // TODO lets assert that we are no longer the leader
+                dumpNodes(count);
+
+                System.out.println("Starting the server");
+                startServer();
+                Thread.sleep(10000);
+
+                for (int i = 0; i < count - 1; i++) {
+                    System.out.println("Calling acquire for node: " + i);
+                    nodes[i].acquire();
+                }
+                dumpNodes(count);
+                System.out.println("Now closing down...");
+            }
+        }
+    }
+
+    protected void dumpNodes(int count) {
+        for (int i = 0; i < count; i++) {
+            WriteLock node = nodes[i];
+            System.out.println("node: " + i + " id: " + node.getId() + " is leader: " + node.isOwner());
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (nodes != null) {
+            for (int i = 0; i < nodes.length; i++) {
+                WriteLock node = nodes[i];
+                if (node != null) {
+                    System.out.println("Closing node: " + i);
+                    node.close();
+                    if (workAroundClosingLastZNodeFails && i == nodes.length - 1) {
+                        System.out.println("Not closing zookeeper: " + i + " due to bug!");
+                    } else {
+                        System.out.println("Closing zookeeper: " + i);
+                        node.getZookeeper().close();
+                        System.out.println("Closed zookeeper: " + i);
+                    }
+                }
+            }
+        }
+        System.out.println("Now lets stop the server");
+        super.tearDown();
+
+    }
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/WriteLockTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZNodeNameTest.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZNodeNameTest.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZNodeNameTest.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZNodeNameTest.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,55 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+import junit.framework.TestCase;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class ZNodeNameTest extends TestCase {
+    public void testOrderWithSamePrefix() throws Exception {
+        String[] names = { "x-3", "x-5", "x-11", "x-1" };
+        String[] expected = { "x-1", "x-3", "x-5", "x-11" };
+        assertOrderedNodeNames(names, expected);
+    }
+    public void testOrderWithDifferentPrefixes() throws Exception {
+        String[] names = { "r-3", "r-2", "r-1", "w-2", "w-1" };
+        String[] expected = { "r-1", "r-2", "r-3", "w-1", "w-2" };
+        assertOrderedNodeNames(names, expected);
+    }
+
+    protected void assertOrderedNodeNames(String[] names, String[] expected) {
+        int size = names.length;
+        assertEquals("The two arrays should be the same size!", names.length, expected.length);
+        SortedSet<ZNodeName> nodeNames = new TreeSet<ZNodeName>();
+        for (String name : names) {
+            nodeNames.add(new ZNodeName(name));
+        }
+
+        int index = 0;
+        for (ZNodeName nodeName : nodeNames) {
+            String name = nodeName.getName();
+            assertEquals("Node " + index, expected[index++], name);
+        }
+    }
+
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZNodeNameTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZooKeeperTestSupport.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZooKeeperTestSupport.java?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZooKeeperTestSupport.java (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZooKeeperTestSupport.java Thu Jul 24 01:49:59 2008
@@ -0,0 +1,89 @@
+/**
+ *
+ * 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.zookeeper.protocols;
+
+import junit.framework.TestCase;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.server.NIOServerCnxn;
+import org.apache.zookeeper.server.ServerStats;
+import org.apache.zookeeper.server.ZooKeeperServer;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class ZooKeeperTestSupport extends TestCase {
+    private static final Logger LOG = Logger.getLogger(WriteLockTest.class);
+
+    protected ZooKeeperServer server;
+    protected int tickTime = 3000;
+    protected int zkPort = 2181;
+    protected NIOServerCnxn.Factory serverFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        startServer();
+        super.setUp();
+
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        stopServer();
+        super.tearDown();
+    }
+
+    protected void startServer() throws IOException, InterruptedException {
+        if (server == null) {
+            File dir = new File("build/" + getClass().getName());
+            File dataDir = new File(dir, "data");
+            File logDir = new File(dir, "log");
+            dataDir.mkdirs();
+            logDir.mkdirs();
+
+            if (ServerStats.getInstance() == null) {
+                try {
+                    ServerStats.registerAsConcrete();
+                } catch (Throwable e) {
+                    LOG.info("Ignored strange assertion failure!: " + e, e);
+                }
+            }
+            server = new ZooKeeperServer(dataDir, logDir, tickTime);
+            server.startup();
+
+
+            ServerStats.registerAsConcrete();
+            serverFactory = new NIOServerCnxn.Factory(zkPort);
+            serverFactory.startup(server);
+
+        }
+    }
+
+    protected void stopServer() {
+        if (serverFactory != null) {
+            serverFactory.shutdown();
+            serverFactory = null;
+        }
+        if (server != null) {
+            server.shutdown();
+            server = null;
+        }
+    }
+}

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/java/org/apache/zookeeper/protocols/ZooKeeperTestSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/activemq/sandbox/zookeeper/zookeeper-protocols/src/test/resources/log4j.properties?rev=679308&view=auto
==============================================================================
--- activemq/sandbox/zookeeper/zookeeper-protocols/src/test/resources/log4j.properties (added)
+++ activemq/sandbox/zookeeper/zookeeper-protocols/src/test/resources/log4j.properties Thu Jul 24 01:49:59 2008
@@ -0,0 +1,36 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+#
+# The logging properties used for eclipse testing, We want to see debug output on the console.
+#
+log4j.rootLogger=INFO, out
+
+#log4j.logger.org.apache.zookeeper.protocols=DEBUG
+log4j.logger.org.apache.zookeeper.server=ERROR
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+# File appender
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d %-5p %c{1} - %m %n
+log4j.appender.file.file=target/test.log

Propchange: activemq/sandbox/zookeeper/zookeeper-protocols/src/test/resources/log4j.properties
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message