You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by br...@apache.org on 2010/01/05 18:32:35 UTC
svn commit: r896143 - in /hadoop/zookeeper/trunk: ./ src/c/include/
src/java/main/org/apache/zookeeper/ src/java/test/org/apache/zookeeper/
src/java/test/org/apache/zookeeper/test/
Author: breed
Date: Tue Jan 5 17:32:35 2010
New Revision: 896143
URL: http://svn.apache.org/viewvc?rev=896143&view=rev
Log:
ZOOKEEPER-544. improve client testability - allow test client to access connected server location
Modified:
hadoop/zookeeper/trunk/CHANGES.txt
hadoop/zookeeper/trunk/src/c/include/zookeeper.h
hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java
hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/TestableZooKeeper.java
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java
Modified: hadoop/zookeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/CHANGES.txt?rev=896143&r1=896142&r2=896143&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/CHANGES.txt (original)
+++ hadoop/zookeeper/trunk/CHANGES.txt Tue Jan 5 17:32:35 2010
@@ -219,6 +219,8 @@
ZOOKEEPER-633. Fetch netty using ivy for bookkeeper (giri via fpj)
+ ZOOKEEPER-544. improve client testability - allow test client to access connected server location (phunt via breed)
+
NEW FEATURES:
ZOOKEEPER-539. generate eclipse project via ant target. (phunt via mahadev)
Modified: hadoop/zookeeper/trunk/src/c/include/zookeeper.h
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/include/zookeeper.h?rev=896143&r1=896142&r2=896143&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/c/include/zookeeper.h (original)
+++ hadoop/zookeeper/trunk/src/c/include/zookeeper.h Tue Jan 5 17:32:35 2010
@@ -1019,6 +1019,8 @@
/**
* \brief enable/disable quorum endpoint order randomization
*
+ * Note: typically this method should NOT be used outside of testing.
+ *
* If passed a non-zero value, will make the client connect to quorum peers
* in the order as specified in the zookeeper_init() call.
* A zero value causes zookeeper_init() to permute the peer endpoints
Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java?rev=896143&r1=896142&r2=896143&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java (original)
+++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ClientCnxn.java Tue Jan 5 17:32:35 2010
@@ -23,6 +23,7 @@
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
@@ -39,8 +40,8 @@
import org.apache.jute.Record;
import org.apache.log4j.Logger;
import org.apache.zookeeper.AsyncCallback.ACLCallback;
-import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
import org.apache.zookeeper.AsyncCallback.Children2Callback;
+import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
import org.apache.zookeeper.AsyncCallback.DataCallback;
import org.apache.zookeeper.AsyncCallback.StatCallback;
import org.apache.zookeeper.AsyncCallback.StringCallback;
@@ -58,8 +59,8 @@
import org.apache.zookeeper.proto.CreateResponse;
import org.apache.zookeeper.proto.ExistsResponse;
import org.apache.zookeeper.proto.GetACLResponse;
-import org.apache.zookeeper.proto.GetChildrenResponse;
import org.apache.zookeeper.proto.GetChildren2Response;
+import org.apache.zookeeper.proto.GetChildrenResponse;
import org.apache.zookeeper.proto.GetDataResponse;
import org.apache.zookeeper.proto.ReplyHeader;
import org.apache.zookeeper.proto.RequestHeader;
@@ -167,15 +168,57 @@
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
- sb.append("sessionId: 0x").append(Long.toHexString(getSessionId()))
- .append("\n");
- sb.append("lastZxid: ").append(lastZxid).append("\n");
- sb.append("xid: ").append(xid).append("\n");
- sb.append("nextAddrToTry: ").append(nextAddrToTry).append("\n");
- sb.append("serverAddrs: ").append(serverAddrs.get(nextAddrToTry))
- .append("\n");
+
+ SocketAddress local = getLocalSocketAddress();
+ SocketAddress remote = getRemoteSocketAddress();
+ sb
+ .append("sessionid:0x").append(Long.toHexString(getSessionId()))
+ .append(" local:").append(local)
+ .append(" remoteserver:").append(remote)
+ .append(" lastZxid:").append(lastZxid)
+ .append(" xid:").append(xid)
+ .append(" sent:").append(sendThread.sentCount)
+ .append(" recv:").append(sendThread.recvCount)
+ .append(" queuedpkts:").append(outgoingQueue.size())
+ .append(" pendingresp:").append(pendingQueue.size())
+ .append(" queuedevents:").append(eventThread.waitingEvents.size());
+
return sb.toString();
}
+
+ /**
+ * Returns the address to which the socket is connected.
+ * @return ip address of the remote side of the connection or null if
+ * not connected
+ */
+ SocketAddress getRemoteSocketAddress() {
+ // a lot could go wrong here, so rather than put in a bunch of code
+ // to check for nulls all down the chain let's do it the simple
+ // yet bulletproof way
+ try {
+ return ((SocketChannel)sendThread.sockKey.channel())
+ .socket().getRemoteSocketAddress();
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the local address to which the socket is bound.
+ * @return ip address of the remote side of the connection or null if
+ * not connected
+ */
+ SocketAddress getLocalSocketAddress() {
+ // a lot could go wrong here, so rather than put in a bunch of code
+ // to check for nulls all down the chain let's do it the simple
+ // yet bulletproof way
+ try {
+ return ((SocketChannel)sendThread.sockKey.channel())
+ .socket().getLocalSocketAddress();
+ } catch (NullPointerException e) {
+ return null;
+ }
+ }
/**
* This class allows us to pass the headers and the relevant records around.
@@ -608,6 +651,9 @@
private long lastPingSentNs;
+ long sentCount = 0;
+ long recvCount = 0;
+
void readLength() throws IOException {
int len = incomingBuffer.getInt();
if (len < 0 || len >= packetLen) {
@@ -758,14 +804,15 @@
+ Long.toHexString(sessionId)
+ ", likely server has closed socket");
}
- if (incomingBuffer.remaining() == 0) {
+ if (!incomingBuffer.hasRemaining()) {
incomingBuffer.flip();
if (incomingBuffer == lenBuffer) {
+ recvCount++;
readLength();
} else if (!initialized) {
readConnectResult();
enableRead();
- if (outgoingQueue.size() > 0) {
+ if (!outgoingQueue.isEmpty()) {
enableWrite();
}
lenBuffer.clear();
@@ -782,9 +829,11 @@
}
if (sockKey.isWritable()) {
synchronized (outgoingQueue) {
- if (outgoingQueue.size() > 0) {
- sock.write(outgoingQueue.getFirst().bb);
- if (outgoingQueue.getFirst().bb.remaining() == 0) {
+ if (!outgoingQueue.isEmpty()) {
+ ByteBuffer pbb = outgoingQueue.getFirst().bb;
+ sock.write(pbb);
+ if (!pbb.hasRemaining()) {
+ sentCount++;
Packet p = outgoingQueue.removeFirst();
if (p.header != null
&& p.header.getType() != OpCode.ping
@@ -795,7 +844,7 @@
}
}
}
- if (outgoingQueue.size() == 0) {
+ if (outgoingQueue.isEmpty()) {
disableWrite();
} else {
enableWrite();
Modified: hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java?rev=896143&r1=896142&r2=896143&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java (original)
+++ hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java Tue Jan 5 17:32:35 2010
@@ -19,6 +19,7 @@
package org.apache.zookeeper;
import java.io.IOException;
+import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -1456,7 +1457,21 @@
public States getState() {
return state;
}
-
+
+ /**
+ * String representation of this ZooKeeper client. Suitable for things
+ * like logging.
+ *
+ * Do NOT count on the format of this string, it may change without
+ * warning.
+ *
+ * @since 3.3.0
+ */
+ @Override
+ public String toString() {
+ return ("State:" + getState().toString() + " " + cnxn);
+ }
+
/*
* Methods to aid in testing follow.
*
@@ -1466,6 +1481,9 @@
/**
* Wait up to wait milliseconds for the underlying threads to shutdown.
* THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
+ *
+ * @since 3.3.0
+ *
* @param wait max wait in milliseconds
* @return true iff all threads are shutdown, otw false
*/
@@ -1478,4 +1496,33 @@
if (cnxn.eventThread.isAlive()) return false;
return true;
}
+
+ /**
+ * Returns the address to which the socket is connected. Useful for testing
+ * against an ensemble - test client may need to know which server
+ * to shutdown if interested in verifying that the code handles
+ * disconnection/reconnection correctly.
+ * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
+ *
+ * @since 3.3.0
+ *
+ * @return ip address of the remote side of the connection or null if
+ * not connected
+ */
+ protected SocketAddress testableRemoteSocketAddress() {
+ return cnxn.getRemoteSocketAddress();
+ }
+
+ /**
+ * Returns the local address to which the socket is bound.
+ * THIS METHOD IS EXPECTED TO BE USED FOR TESTING ONLY!!!
+ *
+ * @since 3.3.0
+ *
+ * @return ip address of the remote side of the connection or null if
+ * not connected
+ */
+ protected SocketAddress testableLocalSocketAddress() {
+ return cnxn.getLocalSocketAddress();
+ }
}
Modified: hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/TestableZooKeeper.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/TestableZooKeeper.java?rev=896143&r1=896142&r2=896143&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/TestableZooKeeper.java (original)
+++ hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/TestableZooKeeper.java Tue Jan 5 17:32:35 2010
@@ -19,6 +19,7 @@
package org.apache.zookeeper;
import java.io.IOException;
+import java.net.SocketAddress;
import java.nio.channels.SocketChannel;
import java.util.List;
@@ -75,4 +76,12 @@
{
return super.testableWaitForShutdown(wait);
}
+
+ public SocketAddress testableLocalSocketAddress() {
+ return super.testableLocalSocketAddress();
+ }
+
+ public SocketAddress testableRemoteSocketAddress() {
+ return super.testableRemoteSocketAddress();
+ }
}
Modified: hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java?rev=896143&r1=896142&r2=896143&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java (original)
+++ hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientTest.java Tue Jan 5 17:32:35 2010
@@ -104,6 +104,23 @@
performClientTest(true);
}
+ /** Exercise the testable functions, verify tostring, etc... */
+ @Test
+ public void testTestability() throws Exception {
+ TestableZooKeeper zk = createClient();
+ try {
+ LOG.info(zk.testableLocalSocketAddress());
+ LOG.info(zk.testableRemoteSocketAddress());
+ LOG.info(zk.toString());
+ } finally {
+ zk.close();
+ zk.testableWaitForShutdown(CONNECTION_TIMEOUT);
+ LOG.info(zk.testableLocalSocketAddress());
+ LOG.info(zk.testableRemoteSocketAddress());
+ LOG.info(zk.toString());
+ }
+ }
+
@Test
public void testACLs() throws Exception {
ZooKeeper zk = null;