Package org.apache.hadoop.hbase.client.coprocessor

Source Code of org.apache.hadoop.hbase.client.coprocessor.Batch$Callback

/*
* Copyright 2010 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.
*/

package org.apache.hadoop.hbase.client.coprocessor;

import org.apache.commons.lang.reflect.MethodUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.ipc.CoprocessorProtocol;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


/**
* A collection of interfaces and utilities used for interacting with custom RPC
* interfaces exposed by Coprocessors.
*/
public abstract class Batch {
  private static Log LOG = LogFactory.getLog(Batch.class);

  /**
   * Creates a new {@link Batch.Call} instance that invokes a method
   * with the given parameters and returns the result.
   *
   * <p>
   * Note that currently the method is naively looked up using the method name
   * and class types of the passed arguments, which means that
   * <em>none of the arguments can be <code>null</code></em>.
   * For more flexibility, see
   * {@link Batch#forMethod(java.lang.reflect.Method, Object...)}.
   * </p>
   *
   * @param protocol the protocol class being called
   * @param method the method name
   * @param args zero or more arguments to be passed to the method
   * (individual args cannot be <code>null</code>!)
   * @param <T> the class type of the protocol implementation being invoked
   * @param <R> the return type for the method call
   * @return a {@code Callable} instance that will invoke the given method
   * and return the results
   * @throws NoSuchMethodException if the method named, with the given argument
   *     types, cannot be found in the protocol class
   * @see Batch#forMethod(java.lang.reflect.Method, Object...)
   * @see org.apache.hadoop.hbase.client.HTable#coprocessorExec(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)
   */
  public static <T extends CoprocessorProtocol,R> Call<T,R> forMethod(
      final Class<T> protocol, final String method, final Object... args)
  throws NoSuchMethodException {
    Class[] types = new Class[args.length];
    for (int i=0; i<args.length; i++) {
      if (args[i] == null) {
        throw new NullPointerException("Method argument cannot be null");
      }
      types[i] = args[i].getClass();
    }

    Method m = MethodUtils.getMatchingAccessibleMethod(protocol, method, types);
    if (m == null) {
      throw new NoSuchMethodException("No matching method found for '" +
          method + "'");
    }

    m.setAccessible(true);
    return forMethod(m, args);
  }

  /**
   * Creates a new {@link Batch.Call} instance that invokes a method
   * with the given parameters and returns the result.
   *
   * @param method the method reference to invoke
   * @param args zero or more arguments to be passed to the method
   * @param <T> the class type of the protocol implementation being invoked
   * @param <R> the return type for the method call
   * @return a {@code Callable} instance that will invoke the given method and
   * return the results
   * @see org.apache.hadoop.hbase.client.HTable#coprocessorExec(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)
   */
  public static <T extends CoprocessorProtocol,R> Call<T,R> forMethod(
      final Method method, final Object... args) {
    return new Call<T,R>() {
        public R call(T instance) throws IOException {
          try {
            if (Proxy.isProxyClass(instance.getClass())) {
              InvocationHandler invoker = Proxy.getInvocationHandler(instance);
              return (R)invoker.invoke(instance, method, args);
            } else {
              LOG.warn("Non proxied invocation of method '"+method.getName()+"'!");
              return (R)method.invoke(instance, args);
            }
          }
          catch (IllegalAccessException iae) {
            throw new IOException("Unable to invoke method '"+
                method.getName()+"'", iae);
          }
          catch (InvocationTargetException ite) {
            throw new IOException(ite.toString(), ite);
          }
          catch (Throwable t) {
            throw new IOException(t.toString(), t);
          }
        }
    };
  }

  /**
   * Defines a unit of work to be executed.
   *
   * <p>
   * When used with
   * {@link org.apache.hadoop.hbase.client.HTable#coprocessorExec(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)}
   * the implementations {@link Batch.Call#call(Object)} method will be invoked
   * with a proxy to the
   * {@link org.apache.hadoop.hbase.ipc.CoprocessorProtocol}
   * sub-type instance.
   * </p>
   * @see org.apache.hadoop.hbase.client.coprocessor
   * @see org.apache.hadoop.hbase.client.HTable#coprocessorExec(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call)
   * @see org.apache.hadoop.hbase.client.HTable#coprocessorExec(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)
   * @param <T> the instance type to be passed to
   * {@link Batch.Call#call(Object)}
   * @param <R> the return type from {@link Batch.Call#call(Object)}
   */
  public static interface Call<T,R> {
    public R call(T instance) throws IOException;
  }

  /**
   * Defines a generic callback to be triggered for each {@link Batch.Call#call(Object)}
   * result.
   *
   * <p>
   * When used with
   * {@link org.apache.hadoop.hbase.client.HTable#coprocessorExec(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)},
   * the implementation's {@link Batch.Callback#update(byte[], byte[], Object)}
   * method will be called with the {@link Batch.Call#call(Object)} return value
   * from each region in the selected range.
   * </p>
   * @param <R> the return type from the associated {@link Batch.Call#call(Object)}
   * @see org.apache.hadoop.hbase.client.HTable#coprocessorExec(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)
   */
  public static interface Callback<R> {
    public void update(byte[] region, byte[] row, R result);
  }
}
TOP

Related Classes of org.apache.hadoop.hbase.client.coprocessor.Batch$Callback

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.