You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by iv...@apache.org on 2012/04/02 12:38:19 UTC

svn commit: r1308294 - in /zookeeper/bookkeeper/trunk: ./ bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/ bookkeeper-server/src/main/java/org/apache/bookkeeper/client/ bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/ bookkeepe...

Author: ivank
Date: Mon Apr  2 10:38:18 2012
New Revision: 1308294

URL: http://svn.apache.org/viewvc?rev=1308294&view=rev
Log:
BOOKKEEPER-135: Fencing does not check the ledger masterPasswd (ivank)

Modified:
    zookeeper/bookkeeper/trunk/CHANGES.txt
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BKException.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerOpenOp.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerRecoveryOp.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingAddOp.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingReadOp.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/ReadLastConfirmedOp.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieClient.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieRecoveryTest.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/TestFencing.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieClientTest.java

Modified: zookeeper/bookkeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/CHANGES.txt?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/CHANGES.txt (original)
+++ zookeeper/bookkeeper/trunk/CHANGES.txt Mon Apr  2 10:38:18 2012
@@ -76,6 +76,8 @@ Trunk (unreleased changes)
 
         BOOKKEEPER-112: Bookie Recovery on an open ledger will cause LedgerHandle#close on that ledger to fail (sijie)
 
+        BOOKKEEPER-135: Fencing does not check the ledger masterPasswd (ivank)
+
       hedwig-server/
       
         BOOKKEEPER-140: Hub server doesn't subscribe remote region correctly when a region is down. (Sijie Gou via ivank)

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Bookie.java Mon Apr  2 10:38:18 2012
@@ -1037,21 +1037,16 @@ public class Bookie extends Thread {
     }
 
     /**
-     * Fences a ledger. From this point on, clients will be unable to 
+     * Fences a ledger. From this point on, clients will be unable to
      * write to this ledger. Only recoveryAddEntry will be
      * able to add entries to the ledger.
      * This method is idempotent. Once a ledger is fenced, it can
      * never be unfenced. Fencing a fenced ledger has no effect.
      */
-    public void fenceLedger(long ledgerId) throws IOException {
-        try {
-            byte[] key = ledgerCache.readMasterKey(ledgerId);
-            LedgerDescriptor handle = handles.getHandle(ledgerId, key);
-            synchronized (handle) {
-                handle.setFenced();
-            }
-        } catch (BookieException e) {
-            throw new IOException("Error fencing", e);
+    public void fenceLedger(long ledgerId, byte[] masterKey) throws IOException, BookieException {
+        LedgerDescriptor handle = handles.getHandle(ledgerId, masterKey);
+        synchronized (handle) {
+            handle.setFenced();
         }
     }
 

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BKException.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BKException.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BKException.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BKException.java Mon Apr  2 10:38:18 2012
@@ -78,6 +78,8 @@ public abstract class BKException extend
             return new BKProtocolVersionException();
         case Code.LedgerFencedException:
             return new BKLedgerFencedException();
+        case Code.UnauthorizedAccessException:
+            return new BKUnauthorizedAccessException();
         default:
             return new BKIllegalOpException();
         }
@@ -108,6 +110,7 @@ public abstract class BKException extend
 
         int IllegalOpException = -100;
         int LedgerFencedException = -101;
+        int UnauthorizedAccessException = -102;
     }
 
     public void setCode(int code) {
@@ -156,6 +159,8 @@ public abstract class BKException extend
             return "Bookie protocol version on server is incompatible with client";
         case Code.LedgerFencedException:
             return "Ledger has been fenced off. Some other client must have opened it to read";
+        case Code.UnauthorizedAccessException:
+            return "Attempted to access ledger using the wrong password";
         default:
             return "Invalid operation";
         }
@@ -268,4 +273,10 @@ public abstract class BKException extend
             super(Code.LedgerFencedException);
         }
     }
+
+    public static class BKUnauthorizedAccessException extends BKException {
+        public BKUnauthorizedAccessException() {
+            super(Code.UnauthorizedAccessException);
+        }
+    }
 }

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerOpenOp.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerOpenOp.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerOpenOp.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerOpenOp.java Mon Apr  2 10:38:18 2012
@@ -141,10 +141,12 @@ class LedgerOpenOp implements DataCallba
             lh.recover(new GenericCallback<Void>() {
                     @Override
                     public void operationComplete(int rc, Void result) {
-                        if (rc != BKException.Code.OK) {
-                            cb.openComplete(BKException.Code.LedgerRecoveryException, null, LedgerOpenOp.this.ctx);
-                        } else {
+                        if (rc == BKException.Code.OK) {
                             cb.openComplete(BKException.Code.OK, lh, LedgerOpenOp.this.ctx);
+                        } else if (rc == BKException.Code.UnauthorizedAccessException) {
+                            cb.openComplete(BKException.Code.UnauthorizedAccessException, null, LedgerOpenOp.this.ctx);
+                        } else {
+                            cb.openComplete(BKException.Code.LedgerRecoveryException, null, LedgerOpenOp.this.ctx);
                         }
                     }
                 });

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerRecoveryOp.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerRecoveryOp.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerRecoveryOp.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerRecoveryOp.java Mon Apr  2 10:38:18 2012
@@ -68,6 +68,8 @@ class LedgerRecoveryOp implements ReadCa
                         lh.lastAddPushed = lh.lastAddConfirmed = data.lastAddConfirmed;
                         lh.length = data.length;
                         doRecoveryRead();
+                    } else if (rc == BKException.Code.UnauthorizedAccessException) {
+                        cb.operationComplete(rc, null);
                     } else {
                         cb.operationComplete(BKException.Code.ReadException, null);
                     }

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingAddOp.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingAddOp.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingAddOp.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingAddOp.java Mon Apr  2 10:38:18 2012
@@ -138,6 +138,10 @@ class PendingAddOp implements WriteCallb
             LOG.warn("Fencing exception on write: " + ledgerId + ", " + entryId);
             lh.handleUnrecoverableErrorDuringAdd(rc);
             return;
+        case BKException.Code.UnauthorizedAccessException:
+            LOG.warn("Unauthorized access exception on write: " + ledgerId + ", " + entryId);
+            lh.handleUnrecoverableErrorDuringAdd(rc);
+            return;
         default:
             LOG.warn("Write did not succeed: " + ledgerId + ", " + entryId);
             lh.handleBookieFailure(addr, bookieIndex);

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingReadOp.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingReadOp.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingReadOp.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/PendingReadOp.java Mon Apr  2 10:38:18 2012
@@ -105,7 +105,7 @@ class PendingReadOp implements Enumerati
         int bookieIndex = lh.distributionSchedule.getBookieIndex(entry.entryId, entry.nextReplicaIndexToReadFrom);
         entry.nextReplicaIndexToReadFrom++;
         lh.bk.bookieClient.readEntry(ensemble.get(bookieIndex), lh.ledgerId, entry.entryId, 
-                                     this, entry, BookieProtocol.FLAG_NONE);
+                                     this, entry);
     }
 
     void logErrorAndReattemptRead(LedgerEntry entry, String errMsg, int rc) {

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/ReadLastConfirmedOp.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/ReadLastConfirmedOp.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/ReadLastConfirmedOp.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/ReadLastConfirmedOp.java Mon Apr  2 10:38:18 2012
@@ -56,18 +56,21 @@ class ReadLastConfirmedOp implements Rea
     }
 
     public void initiate() {
-        initiate(BookieProtocol.FLAG_NONE);
+        for (int i = 0; i < lh.metadata.currentEnsemble.size(); i++) {
+            lh.bk.bookieClient.readEntry(lh.metadata.currentEnsemble.get(i),
+                                         lh.ledgerId,
+                                         BookieProtocol.LAST_ADD_CONFIRMED,
+                                         this, i);
+        }
     }
 
     public void initiateWithFencing() {
-        initiate(BookieProtocol.FLAG_DO_FENCING);
-    }
-
-    private void initiate(short flags) {
         for (int i = 0; i < lh.metadata.currentEnsemble.size(); i++) {
-            lh.bk.bookieClient.readEntry(lh.metadata.currentEnsemble.get(i), lh.ledgerId,
-                                         BookieProtocol.LAST_ADD_CONFIRMED,
-                                         this, i, flags);
+            lh.bk.bookieClient.readEntryAndFenceLedger(lh.metadata.currentEnsemble.get(i),
+                                                       lh.ledgerId,
+                                                       lh.ledgerKey,
+                                                       BookieProtocol.LAST_ADD_CONFIRMED,
+                                                       this, i);
         }
     }
 
@@ -97,6 +100,10 @@ class ReadLastConfirmedOp implements Rea
             heardValidResponse = true;
         }
 
+        if (rc == BKException.Code.UnauthorizedAccessException  && !completed) {
+            cb.readLastConfirmedDataComplete(rc, maxRecoveredData);
+            completed = true;
+        }
         // other return codes dont count as valid responses
         if (heardValidResponse
             && coverageSet.addBookieAndCheckCovered(bookieIndex)

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieClient.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieClient.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieClient.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieClient.java Mon Apr  2 10:38:18 2012
@@ -91,8 +91,28 @@ public class BookieClient {
         });
     }
 
+    public void readEntryAndFenceLedger(final InetSocketAddress addr,
+                                        final long ledgerId,
+                                        final byte[] masterKey,
+                                        final long entryId,
+                                        final ReadEntryCallback cb,
+                                        final Object ctx) {
+        final PerChannelBookieClient client = lookupClient(addr);
+
+        client.connectIfNeededAndDoOp(new GenericCallback<Void>() {
+            @Override
+            public void operationComplete(int rc, Void result) {
+                if (rc != BKException.Code.OK) {
+                    cb.readEntryComplete(rc, ledgerId, entryId, null, ctx);
+                    return;
+                }
+                client.readEntryAndFenceLedger(ledgerId, masterKey, entryId, cb, ctx);
+            }
+        });
+    }
+
     public void readEntry(final InetSocketAddress addr, final long ledgerId, final long entryId,
-                          final ReadEntryCallback cb, final Object ctx, final int options) {
+                          final ReadEntryCallback cb, final Object ctx) {
         final PerChannelBookieClient client = lookupClient(addr);
 
         client.connectIfNeededAndDoOp(new GenericCallback<Void>() {
@@ -103,7 +123,7 @@ public class BookieClient {
                     cb.readEntryComplete(rc, ledgerId, entryId, null, ctx);
                     return;
                 }
-                client.readEntry(ledgerId, entryId, cb, ctx, options);
+                client.readEntry(ledgerId, entryId, cb, ctx);
             }
         });
     }

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieProtocol.java Mon Apr  2 10:38:18 2012
@@ -37,13 +37,21 @@ public interface BookieProtocol {
     /**
      * Current version of the protocol, which client will use. 
      */
-    public static final byte CURRENT_PROTOCOL_VERSION = 1;
-    
+    public static final byte CURRENT_PROTOCOL_VERSION = 2;
+
     /**
      * Entry identifier representing a request to obtain the last add entry confirmed
      */
     public static final long LAST_ADD_CONFIRMED = -1;
 
+    /**
+     * The length of the master key in add packets. This
+     * is fixed at 20 for historic reasons. This is because it
+     * is always generated using the MacDigestManager regardless
+     * of whether Mac is being used for the digest or not
+     */
+    public static final int MASTER_KEY_LENGTH = 20;
+
     /** 
      * The first int of a packet is the header.
      * It contains the version, opCode and flags.

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java Mon Apr  2 10:38:18 2012
@@ -327,14 +327,16 @@ public class BookieServer implements NIO
         switch (h.getOpCode()) {
         case BookieProtocol.ADDENTRY:
             // first read master key
-            masterKey = new byte[20];
-            packet.get(masterKey, 0, 20);
-            // !! fall thru to read ledger id and entry id
-        case BookieProtocol.READENTRY:
+            masterKey = new byte[BookieProtocol.MASTER_KEY_LENGTH];
+            packet.get(masterKey, 0, BookieProtocol.MASTER_KEY_LENGTH);
             ByteBuffer bb = packet.duplicate();
             ledgerId = bb.getLong();
             entryId = bb.getLong();
             break;
+        case BookieProtocol.READENTRY:
+            ledgerId = packet.getLong();
+            entryId = packet.getLong();
+            break;
         }
 
         if (h.getVersion() < BookieProtocol.LOWEST_COMPAT_PROTOCOL_VERSION
@@ -379,7 +381,15 @@ public class BookieServer implements NIO
             try {
                 if ((flags & BookieProtocol.FLAG_DO_FENCING) == BookieProtocol.FLAG_DO_FENCING) {
                     LOG.warn("Ledger " + ledgerId + " fenced by " + src.getPeerName());
-                    bookie.fenceLedger(ledgerId);
+                    if (h.getVersion() >= 2) {
+                        masterKey = new byte[BookieProtocol.MASTER_KEY_LENGTH];
+                        packet.get(masterKey, 0, BookieProtocol.MASTER_KEY_LENGTH);
+
+                        bookie.fenceLedger(ledgerId, masterKey);
+                    } else {
+                        LOG.error("Password not provided, Not safe to fence {}", ledgerId);
+                        throw BookieException.create(BookieException.Code.UnauthorizedAccessException);
+                    }
                 }
                 rsp[1] = bookie.readEntry(ledgerId, entryId);
                 LOG.debug("##### Read entry ##### " + rsp[1].remaining());
@@ -400,6 +410,9 @@ public class BookieServer implements NIO
                     LOG.error("Error reading " + entryId + "@" + ledgerId, e);
                 }
                 errorCode = BookieProtocol.EIO;
+            } catch (BookieException e) {
+                LOG.error("Unauthorized access to ledger " + ledgerId, e);
+                errorCode = BookieProtocol.EUA;
             }
             rsp[0] = buildResponse(errorCode, h.getVersion(), h.getOpCode(), ledgerId, entryId);
 

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/PerChannelBookieClient.java Mon Apr  2 10:38:18 2012
@@ -231,7 +231,7 @@ public class PerChannelBookieClient exte
 
         int totalHeaderSize = 4 // for the length of the packet
                               + 4 // for the type of request
-                              + masterKey.length; // for the master key
+                              + BookieProtocol.MASTER_KEY_LENGTH; // for the master key
 
         try{
             ChannelBuffer header = channel.getConfig().getBufferFactory().getBuffer(totalHeaderSize);
@@ -239,7 +239,7 @@ public class PerChannelBookieClient exte
             header.writeInt(totalHeaderSize - 4 + entrySize);
             header.writeInt(new PacketHeader(BookieProtocol.CURRENT_PROTOCOL_VERSION,
                                              BookieProtocol.ADDENTRY, (short)options).toInt());
-            header.writeBytes(masterKey);
+            header.writeBytes(masterKey, 0, BookieProtocol.MASTER_KEY_LENGTH);
 
             ChannelBuffer wrappedBuffer = ChannelBuffers.wrappedBuffer(header, toSend);
 
@@ -264,7 +264,45 @@ public class PerChannelBookieClient exte
         }
     }
 
-    public void readEntry(final long ledgerId, final long entryId, ReadEntryCallback cb, Object ctx, final int options) {
+    public void readEntryAndFenceLedger(final long ledgerId, byte[] masterKey,
+                                        final long entryId,
+                                        ReadEntryCallback cb, Object ctx) {
+        final CompletionKey key = new CompletionKey(ledgerId, entryId);
+        readCompletions.put(key, new ReadCompletion(cb, ctx));
+
+        int totalHeaderSize = 4 // for the length of the packet
+                              + 4 // for request type
+                              + 8 // for ledgerId
+                              + 8 // for entryId
+                              + BookieProtocol.MASTER_KEY_LENGTH; // for masterKey
+
+        ChannelBuffer tmpEntry = channel.getConfig().getBufferFactory().getBuffer(totalHeaderSize);
+        tmpEntry.writeInt(totalHeaderSize - 4);
+
+        tmpEntry.writeInt(new PacketHeader(BookieProtocol.CURRENT_PROTOCOL_VERSION,
+                                           BookieProtocol.READENTRY,
+                                           BookieProtocol.FLAG_DO_FENCING).toInt());
+        tmpEntry.writeLong(ledgerId);
+        tmpEntry.writeLong(entryId);
+        tmpEntry.writeBytes(masterKey, 0, BookieProtocol.MASTER_KEY_LENGTH);
+
+        ChannelFuture future = channel.write(tmpEntry);
+        future.addListener(new ChannelFutureListener() {
+            @Override
+            public void operationComplete(ChannelFuture future) throws Exception {
+                if (future.isSuccess()) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Successfully wrote request for reading entry: " + entryId + " ledger-id: "
+                                  + ledgerId + " bookie: " + channel.getRemoteAddress());
+                    }
+                } else {
+                    errorOutReadKey(key);
+                }
+            }
+        });
+    }
+
+    public void readEntry(final long ledgerId, final long entryId, ReadEntryCallback cb, Object ctx) {
         final CompletionKey key = new CompletionKey(ledgerId, entryId);
         readCompletions.put(key, new ReadCompletion(cb, ctx));
 
@@ -278,7 +316,7 @@ public class PerChannelBookieClient exte
             tmpEntry.writeInt(totalHeaderSize - 4);
 
             tmpEntry.writeInt(new PacketHeader(BookieProtocol.CURRENT_PROTOCOL_VERSION,
-                                               BookieProtocol.READENTRY, (short)options).toInt());
+                                               BookieProtocol.READENTRY, BookieProtocol.FLAG_NONE).toInt());
             tmpEntry.writeLong(ledgerId);
             tmpEntry.writeLong(entryId);
 
@@ -505,7 +543,10 @@ public class PerChannelBookieClient exte
         case BookieProtocol.EFENCED:
             rc = BKException.Code.LedgerFencedException;
             break;
-        default: 
+        case BookieProtocol.EUA:
+            rc = BKException.Code.UnauthorizedAccessException;
+            break;
+        default:
             LOG.error("Add for ledger: " + ledgerId + ", entry: " + entryId + " failed on bookie: " + addr
                       + " with code: " + rc);
             rc = BKException.Code.WriteException;
@@ -541,6 +582,8 @@ public class PerChannelBookieClient exte
             rc = BKException.Code.NoSuchEntryException;
         } else if (rc == BookieProtocol.EBADVERSION) {
             rc = BKException.Code.ProtocolVersionException;
+        } else if (rc == BookieProtocol.EUA) {
+            rc = BKException.Code.UnauthorizedAccessException;
         } else {
             LOG.error("Read for ledger: " + ledgerId + ", entry: " + entryId + " failed on bookie: " + addr
                       + " with code: " + rc);

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieRecoveryTest.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieRecoveryTest.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieRecoveryTest.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieRecoveryTest.java Mon Apr  2 10:38:18 2012
@@ -482,7 +482,7 @@ public class BookieRecoveryTest extends 
             ReplicationVerificationCallback cb = new ReplicationVerificationCallback(numRequests);
             for (long i = startEntryId; i < endEntryId; i++) {
                 for (InetSocketAddress addr : e.getValue()) {
-                    bkc.bookieClient.readEntry(addr, lh.getId(), i, cb, addr, BookieProtocol.FLAG_NONE);
+                    bkc.bookieClient.readEntry(addr, lh.getId(), i, cb, addr);
                 }
             }
 

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/TestFencing.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/TestFencing.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/TestFencing.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/TestFencing.java Mon Apr  2 10:38:18 2012
@@ -62,7 +62,7 @@ public class TestFencing extends BaseTes
          * Create ledger.
          */
         LedgerHandle writelh = null;
-        writelh = bkc.createLedger(digestType, "".getBytes());
+        writelh = bkc.createLedger(digestType, "password".getBytes());
 
         String tmp = "BookKeeper is cool!";
         for (int i = 0; i < 10; i++) {
@@ -72,7 +72,7 @@ public class TestFencing extends BaseTes
         /*
          * Try to open ledger.
          */
-        LedgerHandle readlh = bkc.openLedger(writelh.getId(), digestType, "".getBytes());
+        LedgerHandle readlh = bkc.openLedger(writelh.getId(), digestType, "password".getBytes());
         // should have triggered recovery and fencing
         
         try {
@@ -346,4 +346,35 @@ public class TestFencing extends BaseTes
             // correct behaviour
         }
     }
+
+    /**
+     * Test that fencing doesn't work with a bad password
+     */
+    @Test
+    public void testFencingBadPassword() throws Exception {
+        /*
+         * Create ledger.
+         */
+        LedgerHandle writelh = null;
+        writelh = bkc.createLedger(digestType, "password1".getBytes());
+
+        String tmp = "BookKeeper is cool!";
+        for (int i = 0; i < 10; i++) {
+            writelh.addEntry(tmp.getBytes());
+        }
+
+        /*
+         * Try to open ledger.
+         */
+        try {
+            LedgerHandle readlh = bkc.openLedger(writelh.getId(), digestType, "badPassword".getBytes());
+            fail("Should not have been able to open with a bad password");
+        } catch (BKException.BKUnauthorizedAccessException uue) {
+            // correct behaviour
+        }
+        // should have triggered recovery and fencing
+
+        writelh.addEntry(tmp.getBytes());
+    }
+
 }

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieClientTest.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieClientTest.java?rev=1308294&r1=1308293&r2=1308294&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieClientTest.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieClientTest.java Mon Apr  2 10:38:18 2012
@@ -138,7 +138,7 @@ public class BookieClientTest extends Te
         bc.addEntry(addr, 1, passwd, 1, bb, wrcb, arc, BookieProtocol.FLAG_NONE);
         synchronized (arc) {
             arc.wait(1000);
-            bc.readEntry(addr, 1, 1, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 1, recb, arc);
             arc.wait(1000);
             assertEquals(0, arc.rc);
             assertEquals(1, arc.entry.getInt());
@@ -157,63 +157,63 @@ public class BookieClientTest extends Te
             notifyObject.wait();
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 6, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 6, recb, arc);
             arc.wait(1000);
             assertEquals(BKException.Code.NoSuchEntryException, arc.rc);
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 7, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 7, recb, arc);
             arc.wait(1000);
             assertEquals(0, arc.rc);
             assertEquals(7, arc.entry.getInt());
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 1, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 1, recb, arc);
             arc.wait(1000);
             assertEquals(0, arc.rc);
             assertEquals(1, arc.entry.getInt());
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 2, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 2, recb, arc);
             arc.wait(1000);
             assertEquals(0, arc.rc);
             assertEquals(2, arc.entry.getInt());
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 3, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 3, recb, arc);
             arc.wait(1000);
             assertEquals(0, arc.rc);
             assertEquals(3, arc.entry.getInt());
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 4, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 4, recb, arc);
             arc.wait(1000);
             assertEquals(BKException.Code.NoSuchEntryException, arc.rc);
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 11, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 11, recb, arc);
             arc.wait(1000);
             assertEquals(0, arc.rc);
             assertEquals(11, arc.entry.getInt());
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 5, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 5, recb, arc);
             arc.wait(1000);
             assertEquals(0, arc.rc);
             assertEquals(5, arc.entry.getInt());
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 10, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 10, recb, arc);
             arc.wait(1000);
             assertEquals(BKException.Code.NoSuchEntryException, arc.rc);
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 12, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 12, recb, arc);
             arc.wait(1000);
             assertEquals(BKException.Code.NoSuchEntryException, arc.rc);
         }
         synchronized (arc) {
-            bc.readEntry(addr, 1, 13, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 1, 13, recb, arc);
             arc.wait(1000);
             assertEquals(BKException.Code.NoSuchEntryException, arc.rc);
         }
@@ -235,7 +235,7 @@ public class BookieClientTest extends Te
         InetSocketAddress addr = new InetSocketAddress("127.0.0.1", port);
         BookieClient bc = new BookieClient(new ClientConfiguration(), channelFactory, executor);
         synchronized (arc) {
-            bc.readEntry(addr, 2, 13, recb, arc, BookieProtocol.FLAG_NONE);
+            bc.readEntry(addr, 2, 13, recb, arc);
             arc.wait(1000);
             assertEquals(BKException.Code.NoSuchEntryException, arc.rc);
         }