Package com.datasift.dropwizard.hbase

Source Code of com.datasift.dropwizard.hbase.InstrumentedHBaseClient

package com.datasift.dropwizard.hbase;

import com.datasift.dropwizard.hbase.metrics.HBaseInstrumentation;
import com.datasift.dropwizard.hbase.scanner.InstrumentedRowScanner;
import com.datasift.dropwizard.hbase.scanner.RowScanner;
import com.datasift.dropwizard.hbase.util.TimerStoppingCallback;
import com.stumbleupon.async.Deferred;
import io.dropwizard.util.Duration;
import io.dropwizard.util.Size;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import org.hbase.async.*;

import java.util.ArrayList;

/**
* An {@link HBaseClient} that is instrumented with {@link Metric}s.
* <p/>
* For each asynchronous request method, a {@link Timer} tracks the time taken for the request.
* <p/>
* This implementation proxies all requests through an underlying {@link HBaseClient}; it merely
* layers instrumentation on top of the underlying {@link HBaseClient}.
*
* @see HBaseInstrumentation
*/
public class InstrumentedHBaseClient implements HBaseClient {

    /**
     * The underlying {@link HBaseClient} to dispatch requests.
     */
    private final HBaseClient client;

    /**
     * The instrumentation for this {@link HBaseClient}.
     */
    private final HBaseInstrumentation metrics;

    /**
     * Creates a new {@link InstrumentedHBaseClient} for the given underlying client.
     * <p/>
     * Instrumentation will be registered with the given {@link MetricRegistry}.
     * <p/>
     * A new {@link HBaseInstrumentation} container will be created for this {@link HBaseClient}
     * with the given {@link MetricRegistry}.
     *
     * @param client   the underlying {@link HBaseClient} implementation to dispatch requests.
     * @param registry the {@link MetricRegistry} to register {@link Metric}s with.
     * @param name     the name of the client to register metrics under.
     */
    public InstrumentedHBaseClient(final HBaseClient client,
                                   final MetricRegistry registry,
                                   final String name) {
        this(client, new HBaseInstrumentation(client, registry, name));
    }

    /**
     * Creates a new {@link InstrumentedHBaseClient} for the given underlying client.
     * <p>
     * Instrumentation will be contained by the given {@link HBaseInstrumentation} instance.
     * <p>
     * <i>Note: this is only really useful for sharing instrumentation between multiple {@link
     * HBaseClient} instances, which only really makes sense for instances configured for the same
     * cluster, but with different client-side settings. <b>Use with caution!!</b></i>
     *
     * @param client  the underlying {@link HBaseClient} implementation to dispatch requests.
     * @param metrics the {@link HBaseInstrumentation} containing the {@link Metric}s to use.
     */
    public InstrumentedHBaseClient(final HBaseClient client, final HBaseInstrumentation metrics) {
        this.client = client;
        this.metrics = metrics;
    }

    /**
     * Get the maximum time for which edits may be buffered before being flushed.
     *
     * @return the maximum time for which edits may be buffered.
     *
     * @see HBaseClient#getFlushInterval()
     */
    public Duration getFlushInterval() {
        return client.getFlushInterval();
    }

    /**
     * Get the capacity of the increment buffer.
     *
     * @return the capacity of the increment buffer.
     *
     * @see HBaseClient#getIncrementBufferSize()
     */
    public Size getIncrementBufferSize() {
        return client.getIncrementBufferSize();
    }

    /**
     * Sets the maximum time for which edits may be buffered before being flushed.
     *
     * @param flushInterval the maximum time for which edits may be buffered.
     *
     * @return the previous flush interval.
     *
     * @see HBaseClient#setFlushInterval(Duration)
     */
    public Duration setFlushInterval(final Duration flushInterval) {
        return client.setFlushInterval(flushInterval);
    }

    /**
     * Sets the capacity of the increment buffer.
     *
     * @param incrementBufferSize the capacity of the increment buffer.
     *
     * @return the previous increment buffer capacity.
     *
     * @see HBaseClient#setIncrementBufferSize(Size)
     */
    public Size setIncrementBufferSize(final Size incrementBufferSize) {
        return client.setIncrementBufferSize(incrementBufferSize);
    }

    /**
     * Atomically creates a cell if, and only if, it doesn't already exist.
     *
     * @param edit the new cell to create.
     *
     * @return true if the cell was created, false if the cell already exists.
     *
     * @see HBaseClient#create(PutRequest)
     */
    public Deferred<Boolean> create(final PutRequest edit) {
        final Timer.Context ctx = metrics.getCreates().time();
        return client.create(edit).addBoth(new TimerStoppingCallback<Boolean>(ctx));
    }

    /**
     * Buffer a durable increment for coalescing.
     *
     * @param request the increment to buffer.
     *
     * @return the new value of the cell, after the increment.
     *
     * @see HBaseClient#bufferIncrement(AtomicIncrementRequest)
     */
    public Deferred<Long> bufferIncrement(final AtomicIncrementRequest request) {
        final Timer.Context ctx = metrics.getIncrements().time();
        return client.bufferIncrement(request).addBoth(new TimerStoppingCallback<Long>(ctx));
    }

    /**
     * Atomically and durably increment a cell value.
     *
     * @param request the increment to make.
     *
     * @return the new value of the cell, after the increment.
     *
     * @see HBaseClient#increment(AtomicIncrementRequest)
     */
    public Deferred<Long> increment(final AtomicIncrementRequest request) {
        final Timer.Context ctx = metrics.getIncrements().time();
        return client.increment(request).addBoth(new TimerStoppingCallback<Long>(ctx));
    }

    /**
     * Atomically increment a cell value, with optional durability.
     *
     * @param request the increment to make.
     * @param durable whether to guarantee this increment succeeded durably.
     *
     * @return the new value of the cell, after the increment.
     *
     * @see HBaseClient#increment(AtomicIncrementRequest, Boolean)
     */
    public Deferred<Long> increment(final AtomicIncrementRequest request, final Boolean durable) {
        final Timer.Context ctx = metrics.getIncrements().time();
        return client.increment(request, durable).addBoth(new TimerStoppingCallback<Long>(ctx));
    }

    /**
     * Atomically compares and sets (CAS) a single cell
     *
     * @param edit the cell to set.
     * @param expected the expected current value.
     *
     * @return true if the expectation was met and the cell was set; otherwise, false.
     *
     * @see HBaseClient#compareAndSet(PutRequest, byte[])
     */
    public Deferred<Boolean> compareAndSet(final PutRequest edit, final byte[] expected) {
        final Timer.Context ctx = metrics.getCompareAndSets().time();
        return client.compareAndSet(edit, expected)
                .addBoth(new TimerStoppingCallback<Boolean>(ctx));
    }

    /**
     * Atomically compares and sets (CAS) a single cell.
     *
     * @param edit the cell to set.
     * @param expected the expected current value.
     *
     * @return true if the expectation was met and the cell was set; otherwise, false.
     *
     * @see HBaseClient#compareAndSet(PutRequest, String)
     */
    public Deferred<Boolean> compareAndSet(final PutRequest edit, final String expected) {
        final Timer.Context ctx = metrics.getCompareAndSets().time();
        return client.compareAndSet(edit, expected)
                .addBoth(new TimerStoppingCallback<Boolean>(ctx));
    }

    /**
     * Deletes the specified cells.
     *
     * @param request the cell(s) to delete.
     *
     * @return a {@link Deferred} indicating when the deletion completes.
     *
     * @see HBaseClient#delete(DeleteRequest)
     */
    public Deferred<Object> delete(final DeleteRequest request) {
        final Timer.Context ctx = metrics.getDeletes().time();
        return client.delete(request).addBoth(new TimerStoppingCallback<>(ctx));
    }

    /**
     * Ensures that a specific table exists.
     *
     * @param table the table to check.
     *
     * @return a {@link Deferred} indicating the completion of the assertion.
     *
     * @throws TableNotFoundException (Deferred) if the table does not exist.
     *
     * @see HBaseClient#ensureTableExists(byte[])
     */
    public Deferred<Object> ensureTableExists(final byte[] table) {
        final Timer.Context ctx = metrics.getAssertions().time();
        return client.ensureTableExists(table).addBoth(new TimerStoppingCallback<>(ctx));
    }

    /**
     * Ensures that a specific table exists.
     *
     * @param table the table to check.
     *
     * @return a {@link Deferred} indicating the completion of the assertion.
     *
     * @throws TableNotFoundException (Deferred) if the table does not exist.
     *
     * @see HBaseClient#ensureTableExists(String)
     */
    public Deferred<Object> ensureTableExists(final String table) {
        final Timer.Context ctx = metrics.getAssertions().time();
        return client.ensureTableExists(table).addBoth(new TimerStoppingCallback<>(ctx));
    }

    /**
     * Ensures that a specific table exists.
     *
     * @param table the table to check.
     *
     * @return a {@link Deferred} indicating the completion of the assertion.
     *
     * @throws TableNotFoundException (Deferred) if the table does not exist.
     * @throws NoSuchColumnFamilyException (Deferred) if the family doesn't exist.
     *
     * @see HBaseClient#ensureTableFamilyExists(byte[], byte[])
     */
    public Deferred<Object> ensureTableFamilyExists(final byte[] table, final byte[] family) {
        final Timer.Context ctx = metrics.getAssertions().time();
        return client.ensureTableFamilyExists(table, family)
                .addBoth(new TimerStoppingCallback<>(ctx));
    }

    /**
     * Ensures that a specific table exists.
     *
     * @param table the table to check.
     *
     * @return a {@link Deferred} indicating the completion of the assertion.
     *
     * @throws TableNotFoundException (Deferred) if the table does not exist.
     * @throws NoSuchColumnFamilyException (Deferred) if the family doesn't exist.
     *
     * @see HBaseClient#ensureTableFamilyExists(String, String)
     */
    public Deferred<Object> ensureTableFamilyExists(final String table, final String family) {
        final Timer.Context ctx = metrics.getAssertions().time();
        return client.ensureTableFamilyExists(table, family)
                .addBoth(new TimerStoppingCallback<>(ctx));
    }

    /**
     * Flushes all requests buffered on the client-side.
     *
     * @return a {@link Deferred} indicating the completion of the flush.
     *
     * @see HBaseClient#flush()
     */
    public Deferred<Object> flush() {
        final Timer.Context ctx = metrics.getFlushes().time();
        return client.flush().addBoth(new TimerStoppingCallback<>(ctx));
    }

    /**
     * Retrieves the specified cells.
     *
     * @param request the cells to get.
     *
     * @return the requested cells.
     *
     * @see HBaseClient#get(GetRequest)
     */
    public Deferred<ArrayList<KeyValue>> get(final GetRequest request) {
        final Timer.Context ctx = metrics.getGets().time();
        return client.get(request).addBoth(new TimerStoppingCallback<ArrayList<KeyValue>>(ctx));
    }

    /**
     * Aqcuire an explicit row lock.
     *
     * @param request the row(s) to lock.
     *
     * @return the row lock.
     *
     * @see HBaseClient#lockRow(RowLockRequest)
     */
    public Deferred<RowLock> lockRow(final RowLockRequest request) {
        final Timer.Context ctx = metrics.getLocks().time();
        return client.lockRow(request).addBoth(new TimerStoppingCallback<RowLock>(ctx));
    }

    /**
     * Create a new {@link RowScanner} for a table.
     *
     * @param table the table to scan.
     *
     * @return a new {@link RowScanner} for the specified table.
     *
     * @see HBaseClient#scan(byte[])
     */
    public RowScanner scan(final byte[] table) {
        final RowScanner scanner = client.scan(table);
        return new InstrumentedRowScanner(scanner, metrics.instrument(scanner));
    }

    /**
     * Create a new {@link RowScanner} for a table.
     *
     * @param table the table to scan.
     *
     * @return a new {@link RowScanner} for the specified table.
     *
     * @see HBaseClient#scan(String)
     */
    public RowScanner scan(final String table) {
        final RowScanner scanner = client.scan(table);
        return new InstrumentedRowScanner(scanner, metrics.instrument(scanner));
    }

    /**
     * Store the specified cell(s).
     *
     * @param request the cell(s) to store.
     *
     * @return a {@link Deferred} indicating the completion of the put operation.
     *
     * @see HBaseClient#put(PutRequest)
     */
    public Deferred<Object> put(final PutRequest request) {
        final Timer.Context ctx = metrics.getPuts().time();
        return client.put(request).addBoth(new TimerStoppingCallback<>(ctx));
    }

    /**
     * Performs a graceful shutdown of this client, flushing any pending requests.
     *
     * @return a {@link Deferred} indicating the completion of the shutdown operation.
     *
     * @see HBaseClient#shutdown()
     */
    public Deferred<Object> shutdown() {
        return client.shutdown();
    }

    /**
     * Get an immutable snapshot of client usage statistics.
     *
     * @return an immutable snapshot of client usage statistics.
     *
     * @see HBaseClient#stats()
     */
    public ClientStats stats() {
        return client.stats();
    }

    /**
     * Get the underlying {@link org.jboss.netty.util.Timer} used by the client.
     *
     * @return the underlying {@link org.jboss.netty.util.Timer} used by the async client.
     *
     * @see HBaseClient#getTimer()
     */
    public org.jboss.netty.util.Timer getTimer() {
        return client.getTimer();
    }

    /**
     * Release an explicit row lock.
     *
     * @param lock the lock to release.
     *
     * @return a {@link Deferred} indicating the completion of the unlock operation.
     *
     * @see HBaseClient#unlockRow(RowLock)
     */
    public Deferred<Object> unlockRow(final RowLock lock) {
        final Timer.Context ctx = metrics.getUnlocks().time();
        return client.unlockRow(lock).addBoth(new TimerStoppingCallback<>(ctx));
    }
}
TOP

Related Classes of com.datasift.dropwizard.hbase.InstrumentedHBaseClient

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.