Package com.yahoo.omid.tso.persistence

Source Code of com.yahoo.omid.tso.persistence.BookKeeperStateLogger$LedgerIdSetCallback

/**
* Copyright (c) 2011 Yahoo! Inc. All rights reserved.
*
* Licensed 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. See accompanying LICENSE file.
*/


package com.yahoo.omid.tso.persistence;


/**
* BookKeeper implementation of StateLogger.
*/

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import org.apache.bookkeeper.client.AsyncCallback;
import org.apache.bookkeeper.client.AsyncCallback.AddCallback;
import org.apache.bookkeeper.client.AsyncCallback.CreateCallback;
import org.apache.bookkeeper.client.BKException;
import org.apache.bookkeeper.client.BookKeeper;
import org.apache.bookkeeper.client.LedgerHandle;
import org.apache.bookkeeper.conf.ClientConfiguration;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.AsyncCallback.StringCallback;
import org.apache.zookeeper.AsyncCallback.StatCallback;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.yahoo.omid.tso.TSOHandler;
import com.yahoo.omid.tso.TSOServerConfig;
import com.yahoo.omid.tso.persistence.StateLogger;
import com.yahoo.omid.tso.persistence.LoggerAsyncCallback.LoggerInitCallback;
import com.yahoo.omid.tso.persistence.LoggerAsyncCallback.BuilderInitCallback;
import com.yahoo.omid.tso.persistence.LoggerAsyncCallback.AddRecordCallback;
import com.yahoo.omid.tso.persistence.LoggerConstants;
import com.yahoo.omid.tso.persistence.LoggerException.Code;

class BookKeeperStateLogger implements StateLogger {
    private static final Log LOG = LogFactory.getLog(BookKeeperStateLogger.class);
   
    private ZooKeeper zk;
    private BookKeeper bk;
    private LedgerHandle lh;
   
   
   
    /**
     * We try to acquire a lock for this primary first. If we succeed, then we check
     * if there is a ledger to recover from.
     *
     * The next two classes implement asynchronously the sequence of
     * operations to write the ledger id.
     */
   
   
    class LedgerIdCreateCallback implements StringCallback {
        LoggerInitCallback cb;
        byte[] ledgerId;
       
        LedgerIdCreateCallback (LoggerInitCallback cb, byte[] ledgerId){
            this.cb = cb;
            this.ledgerId = ledgerId;
        }
       
        public void processResult(int rc, String path, Object ctx, String name){
            if(rc == KeeperException.Code.OK.intValue()){
                if(LOG.isDebugEnabled()){
                    LOG.debug("Created znode succesfully: " + name);
                }
               
                BookKeeperStateLogger.this.enabled = true;
                cb.loggerInitComplete(Code.OK, BookKeeperStateLogger.this, ctx);
            } else if(rc != KeeperException.Code.NODEEXISTS.intValue()){
                LOG.warn("Node exists: " + name);
                cb.loggerInitComplete(Code.INITLOCKFAILED, BookKeeperStateLogger.this, ctx);
            } else {
                zk.setData(LoggerConstants.OMID_LEDGER_ID_PATH,
                                                ledgerId,
                                                -1,
                                                new LedgerIdSetCallback(cb),
                                                ctx);
            }        
        }
    }
   
    class LedgerIdSetCallback implements StatCallback {
        LoggerInitCallback cb;
       
        LedgerIdSetCallback (LoggerInitCallback cb){
            this.cb = cb;
        }
       
        public void processResult(int rc, String path, Object ctx, Stat stat){
            if(rc == KeeperException.Code.OK.intValue()){
                LOG.debug("Set ledger id");
                BookKeeperStateLogger.this.enabled = true;
                cb.loggerInitComplete(Code.OK, BookKeeperStateLogger.this, ctx);
            } else {
                cb.loggerInitComplete(Code.ZKOPFAILED, BookKeeperStateLogger.this, ctx);
            }        
        }
       
    }
   
    /**
     * Flag to determine whether this logger is operating or not.
     */
    boolean enabled = false;
   
    /**
     * Constructor creates a zookeeper and a bookkeeper objects.
     */
    BookKeeperStateLogger(ZooKeeper zk) {
        if(LOG.isDebugEnabled()){
            LOG.debug("Constructing Logger");
        }
       
        this.zk = zk;
    }
   
    /**
     * Watcher for the zookeeper object.
     */
   
    class LoggerWatcher implements Watcher{
       public void process(WatchedEvent event){
            if(event.getState() != Watcher.Event.KeeperState.SyncConnected)
                shutdown();
        }
    }
       
       
    /**
     * Initializes this logger object to add records. Implements the initialize
     * method of the StateLogger interface.
     *
     * @param cb
     * @param ctx
     */
   
    @Override
    public void initialize(final LoggerInitCallback cb, Object ctx)
    throws LoggerException {
        TSOServerConfig config = ((BookKeeperStateBuilder.Context)ctx).config;
       
        /*
         * Create new ledger for adding records
         */
        try{
            bk = new BookKeeper(new ClientConfiguration(), zk);
        } catch (Exception e) {
            LOG.error("Exception while initializing bookkeeper", e);
            throw new LoggerException.BKOpFailedException()
        }
       
        bk.asyncCreateLedger(config.getEnsembleSize(),
                                        config.getQuorumSize(),
                                        BookKeeper.DigestType.CRC32,
                                        "flavio was here".getBytes(),
                                        new CreateCallback(){           
            @Override
            public void createComplete(int rc, LedgerHandle lh, Object ctx){
                if(rc == BKException.Code.OK){
                    try{
                        BookKeeperStateLogger.this.lh = lh;
                                                   
                        ByteArrayOutputStream bos = new ByteArrayOutputStream()
                        DataOutputStream dos = new DataOutputStream(bos)
                        dos.writeLong(lh.getId());
                                                 
                        zk.create(LoggerConstants.OMID_LEDGER_ID_PATH,
                                                        bos.toByteArray(),
                                                        Ids.OPEN_ACL_UNSAFE,
                                                        CreateMode.PERSISTENT,
                                                        new LedgerIdCreateCallback(cb, bos.toByteArray()),
                                                        ctx);    
                    } catch (IOException e) {
                        LOG.error("Failed to write to zookeeper. ", e );
                        cb.loggerInitComplete(Code.BKOPFAILED, BookKeeperStateLogger.this, ctx);
                    }
                } else {
                    LOG.error("Failed to create ledger. " + BKException.getMessage(rc));
                    cb.loggerInitComplete(Code.BKOPFAILED, BookKeeperStateLogger.this, ctx);
                }
            }
        }, ctx);
    }
   
   
    /**
     * Adds a record to the log of operations. The record is a byte array.
     *
     * @param record
     * @param cb
     * @param ctx
     */
    @Override
    public void addRecord(byte[] record, final AddRecordCallback cb, Object ctx) {
        if(LOG.isDebugEnabled()){
            LOG.debug("Adding record.");
        }
       
        if(!enabled){
            cb.addRecordComplete(Code.LOGGERDISABLED, ctx);
            return;
        }
       
        this.lh.asyncAddEntry(record,
            new AddCallback() {
            @Override
            public void addComplete(int rc, LedgerHandle lh, long entryId, Object ctx) {
                if(LOG.isDebugEnabled()){
                    LOG.info("Add to ledger complete: " + lh.getId() + ", " + entryId);
                }
                if (rc != BKException.Code.OK) {
                    LOG.error("Asynchronous add entry failed: " + BKException.getMessage(rc));
                    cb.addRecordComplete(Code.ADDFAILED, ctx);
                } else {
                    cb.addRecordComplete(Code.OK, ctx);
                }
            }
        }, ctx);        
    }
   
   
    /**
     * Shuts down this logger.
     *
     */
    public void shutdown(){
        enabled = false;
        try{
            try{
                if(zk.getState() == ZooKeeper.States.CONNECTED){
                    zk.delete(LoggerConstants.OMID_LEDGER_ID_PATH, -1);
                }
            } catch (Exception e) {
                LOG.warn("Exception while deleting lock znode", e);
            }
            if(this.bk != null) bk.close();
            if(this.zk != null) zk.close();
        } catch (InterruptedException e) {
            LOG.warn("Interrupted while closing logger.", e);
        } catch (BKException e) {
            LOG.warn("Exception while closing BookKeeper object.", e);
        }
    }
  
}
TOP

Related Classes of com.yahoo.omid.tso.persistence.BookKeeperStateLogger$LedgerIdSetCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.