public virtual void TestEmptyInputStream()
        {
            ZooKeeper  zk  = BKJMUtil.ConnectZooKeeper();
            BookKeeper bkc = new BookKeeper(new ClientConfiguration(), zk);

            try
            {
                LedgerHandle lh = bkc.CreateLedger(BookKeeper.DigestType.Crc32, Sharpen.Runtime.GetBytesForString
                                                       ("foobar"));
                lh.Close();
                EditLogLedgerMetadata metadata = new EditLogLedgerMetadata("/foobar", HdfsConstants
                                                                           .NamenodeLayoutVersion, lh.GetId(), unchecked ((int)(0x1234)));
                try
                {
                    new BookKeeperEditLogInputStream(lh, metadata, -1);
                    NUnit.Framework.Assert.Fail("Shouldn't get this far, should have thrown");
                }
                catch (IOException ioe)
                {
                    NUnit.Framework.Assert.IsTrue(ioe.Message.Contains("Invalid first bk entry to read"
                                                                       ));
                }
                metadata = new EditLogLedgerMetadata("/foobar", HdfsConstants.NamenodeLayoutVersion
                                                     , lh.GetId(), unchecked ((int)(0x1234)));
                try
                {
                    new BookKeeperEditLogInputStream(lh, metadata, 0);
                    NUnit.Framework.Assert.Fail("Shouldn't get this far, should have thrown");
                }
                catch (IOException ioe)
                {
                    NUnit.Framework.Assert.IsTrue(ioe.Message.Contains("Invalid first bk entry to read"
                                                                       ));
                }
            }
            finally
            {
                bkc.Close();
                zk.Close();
            }
        }
Exemplo n.º 2
0
        /// <summary>Start a new log segment in a BookKeeper ledger.</summary>
        /// <remarks>
        /// Start a new log segment in a BookKeeper ledger.
        /// First ensure that we have the write lock for this journal.
        /// Then create a ledger and stream based on that ledger.
        /// The ledger id is written to the inprogress znode, so that in the
        /// case of a crash, a recovery process can find the ledger we were writing
        /// to when we crashed.
        /// </remarks>
        /// <param name="txId">First transaction id to be written to the stream</param>
        /// <exception cref="System.IO.IOException"/>
        public override EditLogOutputStream StartLogSegment(long txId, int layoutVersion)
        {
            CheckEnv();
            if (txId <= maxTxId.Get())
            {
                throw new IOException("We've already seen " + txId + ". A new stream cannot be created with it"
                                      );
            }
            try
            {
                string existingInprogressNode = ci.Read();
                if (null != existingInprogressNode && zkc.Exists(existingInprogressNode, false) !=
                    null)
                {
                    throw new IOException("Inprogress node already exists");
                }
                if (currentLedger != null)
                {
                    // bookkeeper errored on last stream, clean up ledger
                    currentLedger.Close();
                }
                currentLedger = bkc.CreateLedger(ensembleSize, quorumSize, ackQuorumSize, BookKeeper.DigestType
                                                 .Mac, Sharpen.Runtime.GetBytesForString(digestpw, Charsets.Utf8));
            }
            catch (BKException bke)
            {
                throw new IOException("Error creating ledger", bke);
            }
            catch (KeeperException ke)
            {
                throw new IOException("Error in zookeeper while creating ledger", ke);
            }
            catch (Exception ie)
            {
                Sharpen.Thread.CurrentThread().Interrupt();
                throw new IOException("Interrupted creating ledger", ie);
            }
            try
            {
                string znodePath        = InprogressZNode(txId);
                EditLogLedgerMetadata l = new EditLogLedgerMetadata(znodePath, layoutVersion, currentLedger
                                                                    .GetId(), txId);

                /* Write the ledger metadata out to the inprogress ledger znode
                 * This can fail if for some reason our write lock has
                 * expired (@see WriteLock) and another process has managed to
                 * create the inprogress znode.
                 * In this case, throw an exception. We don't want to continue
                 * as this would lead to a split brain situation.
                 */
                l.Write(zkc, znodePath);
                maxTxId.Store(txId);
                ci.Update(znodePath);
                return(new BookKeeperEditLogOutputStream(conf, currentLedger));
            }
            catch (KeeperException ke)
            {
                CleanupLedger(currentLedger);
                throw new IOException("Error storing ledger metadata", ke);
            }
        }