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 2011/10/27 18:53:35 UTC

svn commit: r1189867 - in /zookeeper/bookkeeper/trunk: ./ bookkeeper-server/src/main/java/org/apache/bookkeeper/client/ bookkeeper-server/src/test/java/org/apache/bookkeeper/test/

Author: ivank
Date: Thu Oct 27 16:53:34 2011
New Revision: 1189867

URL: http://svn.apache.org/viewvc?rev=1189867&view=rev
Log:
BOOKKEEPER-93: bookkeeper doesn't work correctly on OpenLedgerNoRecovery (Sijie Guo via ivank)

Modified:
    zookeeper/bookkeeper/trunk/CHANGES.txt
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerCreateOp.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerOpenOp.java
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieReadWriteTest.java

Modified: zookeeper/bookkeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/CHANGES.txt?rev=1189867&r1=1189866&r2=1189867&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/CHANGES.txt (original)
+++ zookeeper/bookkeeper/trunk/CHANGES.txt Thu Oct 27 16:53:34 2011
@@ -56,6 +56,8 @@ BUGFIXES:
 
   BOOKKEEPER-89: Bookkeeper API changes for initial Bookkeeper release (ivank)
 
+  BOOKKEEPER-93: bookkeeper doesn't work correctly on OpenLedgerNoRecovery (Sijie Guo via ivank)
+
  hedwig-server/
 
   BOOKKEEPER-43: NullPointException when releasing topic (Sijie Guo via breed)

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerCreateOp.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerCreateOp.java?rev=1189867&r1=1189866&r2=1189867&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerCreateOp.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerCreateOp.java Thu Oct 27 16:53:34 2011
@@ -140,7 +140,7 @@ class LedgerCreateOp implements StringCa
          */
         metadata.addEnsemble(new Long(0), ensemble);
         try {
-            lh = new LedgerHandle(bk, ledgerId, metadata, digestType, passwd);
+            lh = new LedgerHandle(bk, ledgerId, metadata, digestType, passwd, false);
         } catch (GeneralSecurityException e) {
             LOG.error("Security exception while creating ledger: " + ledgerId, e);
             cb.createComplete(BKException.Code.DigestNotInitializedException, null, this.ctx);

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java?rev=1189867&r1=1189866&r2=1189867&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java Thu Oct 27 16:53:34 2011
@@ -65,6 +65,7 @@ public class LedgerHandle {
     long length;
     final DigestManager macManager;
     final DistributionSchedule distributionSchedule;
+    final boolean readOnly;
 
     final Semaphore opCounterSem;
     private Integer throttling = 5000;
@@ -72,10 +73,11 @@ public class LedgerHandle {
     final Queue<PendingAddOp> pendingAddOps = new ArrayDeque<PendingAddOp>();
 
     LedgerHandle(BookKeeper bk, long ledgerId, LedgerMetadata metadata,
-                 DigestType digestType, byte[] password)
+                 DigestType digestType, byte[] password, boolean readOnly)
             throws GeneralSecurityException, NumberFormatException {
         this.bk = bk;
         this.metadata = metadata;
+        this.readOnly = readOnly;
         if (metadata.isClosed()) {
             lastAddConfirmed = lastAddPushed = metadata.close;
             length = metadata.length;
@@ -241,6 +243,11 @@ public class LedgerHandle {
      * @param rc
      */
     private void asyncClose(final CloseCallback cb, final Object ctx, final int rc) {
+        // in unsafe read mode, we should not close ledger, just callback
+        if (readOnly) {
+            cb.closeComplete(BKException.Code.OK, this, ctx);
+            return;
+        }
 
         bk.mainWorkerPool.submitOrdered(ledgerId, new SafeRunnable() {
 
@@ -397,6 +404,11 @@ public class LedgerHandle {
      */
     public void asyncAddEntry(final byte[] data, final int offset, final int length,
                               final AddCallback cb, final Object ctx) {
+        if (readOnly) {
+            LOG.error("Tries to add entry on a Read-Only ledger handle");
+            cb.addComplete(BKException.Code.IllegalOpException, this, -1, ctx);
+            return;
+        }
         if (offset < 0 || length < 0
                 || (offset + length) > data.length) {
             throw new ArrayIndexOutOfBoundsException(

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=1189867&r1=1189866&r2=1189867&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 Thu Oct 27 16:53:34 2011
@@ -24,6 +24,7 @@ package org.apache.bookkeeper.client;
 import java.io.IOException;
 import java.security.GeneralSecurityException;
 import org.apache.bookkeeper.client.AsyncCallback.OpenCallback;
+import org.apache.bookkeeper.client.AsyncCallback.ReadLastConfirmedCallback;
 import org.apache.bookkeeper.client.BookKeeper.DigestType;
 import org.apache.bookkeeper.util.StringUtils;
 import org.apache.log4j.Logger;
@@ -111,7 +112,7 @@ class LedgerOpenOp implements DataCallba
         }
 
         try {
-            lh = new LedgerHandle(bk, ledgerId, metadata, digestType, passwd);
+            lh = new LedgerHandle(bk, ledgerId, metadata, digestType, passwd, unsafe);
         } catch (GeneralSecurityException e) {
             LOG.error("Security exception while opening ledger: " + ledgerId, e);
             cb.openComplete(BKException.Code.DigestNotInitializedException, null, this.ctx);
@@ -128,16 +129,33 @@ class LedgerOpenOp implements DataCallba
             return;
         }
 
-        if(!unsafe)
+        if(!unsafe) {
             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 {
-                    cb.openComplete(BKException.Code.OK, lh, LedgerOpenOp.this.ctx);
+                @Override
+                public void operationComplete(int rc, Void result) {
+                    if (rc != BKException.Code.OK) {
+                        cb.openComplete(BKException.Code.LedgerRecoveryException, null, LedgerOpenOp.this.ctx);
+                    } else {
+                        cb.openComplete(BKException.Code.OK, lh, LedgerOpenOp.this.ctx);
+                    }
                 }
-            }
-        });
+            });
+        } else {
+            lh.asyncReadLastConfirmed(new ReadLastConfirmedCallback() {
+
+                @Override
+                public void readLastConfirmedComplete(int rc,
+                        long lastConfirmed, Object ctx) {
+                    if (rc != BKException.Code.OK) {
+                        cb.openComplete(BKException.Code.ReadException, null, LedgerOpenOp.this.ctx);
+                    } else {
+                        lh.lastAddConfirmed = lh.lastAddPushed = lastConfirmed;
+                        cb.openComplete(BKException.Code.OK, lh, LedgerOpenOp.this.ctx);
+                    }
+                }
+                
+            }, null);
+            
+        }
     }
 }

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieReadWriteTest.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieReadWriteTest.java?rev=1189867&r1=1189866&r2=1189867&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieReadWriteTest.java (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/BookieReadWriteTest.java Thu Oct 27 16:53:34 2011
@@ -50,6 +50,7 @@ import org.apache.log4j.Logger;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.Watcher;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -812,7 +813,8 @@ public class BookieReadWriteTest extends
             fail("Test failed due to interruption");
         }
     }
-
+    
+    @Test
     public void testReadFromOpenLedger() throws IOException {
         try {
             // Create a ledger
@@ -830,8 +832,26 @@ public class BookieReadWriteTest extends
                 lh.addEntry(entry.array());
                 if(i == numEntriesToWrite/2) {
                     LedgerHandle lhOpen = bkc.openLedgerNoRecovery(ledgerId, digestType, ledgerPassword);
-                    Enumeration<LedgerEntry> readEntry = lh.readEntries(i, i);
+                    // no recovery opened ledger 's last confirmed entry id is less than written
+                    // and it just can read until (i-1)
+                    int toRead = i - 1;
+                    Enumeration<LedgerEntry> readEntry = lhOpen.readEntries(toRead, toRead);
                     assertTrue("Enumeration of ledger entries has no element", readEntry.hasMoreElements() == true);
+                    LedgerEntry e = readEntry.nextElement();
+                    assertEquals(toRead, e.getEntryId());
+                    Assert.assertArrayEquals(entries.get(toRead), e.getEntry());
+                    // should not written to a read only ledger
+                    try {
+                        lhOpen.addEntry(entry.array());
+                        fail("Should have thrown an exception here");
+                    } catch (BKException.BKIllegalOpException bkioe) {
+                        // this is the correct response
+                    } catch (Exception ex) {
+                        LOG.error("Unexpected exception", ex);
+                        fail("Unexpected exception");
+                    }
+                    // close read only ledger should not change metadata
+                    lhOpen.close();
                 }
             }