org.apache.hadoop.hbase.ipc.TestIPC.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hbase.ipc.TestIPC.java

Source

/**
  *
  * 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.ipc;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.internal.verification.VerificationModeFactory.times;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.net.SocketFactory;

import com.google.protobuf.BlockingRpcChannel;
import com.google.protobuf.RpcCallback;
import com.google.protobuf.RpcChannel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.channel.socket.SocketChannel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellScannable;
import org.apache.hadoop.hbase.CellScanner;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.Waiter;
import org.apache.hadoop.hbase.testclassification.RPCTests;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RowMutations;
import org.apache.hadoop.hbase.codec.Codec;
import org.apache.hadoop.hbase.ipc.protobuf.generated.TestProtos.EchoRequestProto;
import org.apache.hadoop.hbase.ipc.protobuf.generated.TestProtos.EchoResponseProto;
import org.apache.hadoop.hbase.ipc.protobuf.generated.TestProtos.EmptyRequestProto;
import org.apache.hadoop.hbase.ipc.protobuf.generated.TestProtos.EmptyResponseProto;
import org.apache.hadoop.hbase.ipc.protobuf.generated.TestRpcServiceProtos;
import org.apache.hadoop.hbase.monitoring.MonitoredRPCHandler;
import org.apache.hadoop.hbase.protobuf.RequestConverter;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.util.StringUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.protobuf.BlockingService;
import com.google.protobuf.ByteString;
import com.google.protobuf.Descriptors.MethodDescriptor;
import com.google.protobuf.Message;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;

/**
 * Some basic ipc tests.
 */
@Category({ RPCTests.class, SmallTests.class })
public class TestIPC {
    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();

    public static final Log LOG = LogFactory.getLog(TestIPC.class);

    static byte[] CELL_BYTES = Bytes.toBytes("xyz");
    static Cell CELL = new KeyValue(CELL_BYTES, CELL_BYTES, CELL_BYTES, CELL_BYTES);
    static byte[] BIG_CELL_BYTES = new byte[10 * 1024];
    static Cell BIG_CELL = new KeyValue(CELL_BYTES, CELL_BYTES, CELL_BYTES, BIG_CELL_BYTES);
    private final static Configuration CONF = HBaseConfiguration.create();
    // We are using the test TestRpcServiceProtos generated classes and Service because they are
    // available and basic with methods like 'echo', and ping.  Below we make a blocking service
    // by passing in implementation of blocking interface.  We use this service in all tests that
    // follow.
    private static final BlockingService SERVICE = TestRpcServiceProtos.TestProtobufRpcProto
            .newReflectiveBlockingService(new TestRpcServiceProtos.TestProtobufRpcProto.BlockingInterface() {

                @Override
                public EmptyResponseProto ping(RpcController controller, EmptyRequestProto request)
                        throws ServiceException {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public EmptyResponseProto error(RpcController controller, EmptyRequestProto request)
                        throws ServiceException {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public EchoResponseProto echo(RpcController controller, EchoRequestProto request)
                        throws ServiceException {
                    if (controller instanceof PayloadCarryingRpcController) {
                        PayloadCarryingRpcController pcrc = (PayloadCarryingRpcController) controller;
                        // If cells, scan them to check we are able to iterate what we were given and since this is
                        // an echo, just put them back on the controller creating a new block.  Tests our block
                        // building.
                        CellScanner cellScanner = pcrc.cellScanner();
                        List<Cell> list = null;
                        if (cellScanner != null) {
                            list = new ArrayList<Cell>();
                            try {
                                while (cellScanner.advance()) {
                                    list.add(cellScanner.current());
                                }
                            } catch (IOException e) {
                                throw new ServiceException(e);
                            }
                        }
                        cellScanner = CellUtil.createCellScanner(list);
                        ((PayloadCarryingRpcController) controller).setCellScanner(cellScanner);
                    }
                    return EchoResponseProto.newBuilder().setMessage(request.getMessage()).build();
                }
            });

    /**
     * Instance of server.  We actually don't do anything speical in here so could just use
     * HBaseRpcServer directly.
     */
    private static class TestRpcServer extends RpcServer {

        TestRpcServer() throws IOException {
            this(new FifoRpcScheduler(CONF, 1));
        }

        TestRpcServer(RpcScheduler scheduler) throws IOException {
            super(null, "testRpcServer", Lists.newArrayList(new BlockingServiceAndInterface(SERVICE, null)),
                    new InetSocketAddress("localhost", 0), CONF, scheduler);
        }

        @Override
        public Pair<Message, CellScanner> call(BlockingService service, MethodDescriptor md, Message param,
                CellScanner cellScanner, long receiveTime, MonitoredRPCHandler status) throws IOException {
            return super.call(service, md, param, cellScanner, receiveTime, status);
        }
    }

    /**
     * Ensure we do not HAVE TO HAVE a codec.
     * @throws InterruptedException
     * @throws IOException
     */
    @Test
    public void testNoCodec() throws InterruptedException, IOException {
        Configuration conf = HBaseConfiguration.create();
        RpcClientImpl client = new RpcClientImpl(conf, HConstants.CLUSTER_ID_DEFAULT) {
            @Override
            Codec getCodec() {
                return null;
            }
        };
        TestRpcServer rpcServer = new TestRpcServer();
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            final String message = "hello";
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage(message).build();
            Pair<Message, CellScanner> r = client.call(null, md, param, md.getOutputType().toProto(),
                    User.getCurrent(), address);
            assertTrue(r.getSecond() == null);
            // Silly assertion that the message is in the returned pb.
            assertTrue(r.getFirst().toString().contains(message));
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    /**
     * Ensure we do not HAVE TO HAVE a codec.
     *
     * @throws InterruptedException
     * @throws IOException
     */
    @Test
    public void testNoCodecAsync() throws InterruptedException, IOException, ServiceException {
        Configuration conf = HBaseConfiguration.create();
        AsyncRpcClient client = new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null) {
            @Override
            Codec getCodec() {
                return null;
            }
        };
        TestRpcServer rpcServer = new TestRpcServer();
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            final String message = "hello";
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage(message).build();

            BlockingRpcChannel channel = client.createBlockingRpcChannel(
                    ServerName.valueOf(address.getHostName(), address.getPort(), System.currentTimeMillis()),
                    User.getCurrent(), 0);

            PayloadCarryingRpcController controller = new PayloadCarryingRpcController();
            Message response = channel.callBlockingMethod(md, controller, param, md.getOutputType().toProto());

            assertTrue(controller.cellScanner() == null);
            // Silly assertion that the message is in the returned pb.
            assertTrue(response.toString().contains(message));
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    /**
     * It is hard to verify the compression is actually happening under the wraps.  Hope that if
     * unsupported, we'll get an exception out of some time (meantime, have to trace it manually
     * to confirm that compression is happening down in the client and server).
     * @throws IOException
     * @throws InterruptedException
     * @throws SecurityException
     * @throws NoSuchMethodException
     */
    @Test
    public void testCompressCellBlock()
            throws IOException, InterruptedException, SecurityException, NoSuchMethodException, ServiceException {
        Configuration conf = new Configuration(HBaseConfiguration.create());
        conf.set("hbase.client.rpc.compressor", GzipCodec.class.getCanonicalName());
        doSimpleTest(new RpcClientImpl(conf, HConstants.CLUSTER_ID_DEFAULT));

        // Another test for the async client
        doAsyncSimpleTest(new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null));
    }

    private void doSimpleTest(final RpcClientImpl client) throws InterruptedException, IOException {
        TestRpcServer rpcServer = new TestRpcServer();
        List<Cell> cells = new ArrayList<Cell>();
        int count = 3;
        for (int i = 0; i < count; i++)
            cells.add(CELL);
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();

            PayloadCarryingRpcController pcrc = new PayloadCarryingRpcController(CellUtil.createCellScanner(cells));
            Pair<Message, CellScanner> r = client.call(pcrc, md, param, md.getOutputType().toProto(),
                    User.getCurrent(), address);
            int index = 0;
            while (r.getSecond().advance()) {
                assertTrue(CELL.equals(r.getSecond().current()));
                index++;
            }
            assertEquals(count, index);
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    private void doAsyncSimpleTest(final AsyncRpcClient client)
            throws InterruptedException, IOException, ServiceException {
        TestRpcServer rpcServer = new TestRpcServer();
        List<Cell> cells = new ArrayList<Cell>();
        int count = 3;
        for (int i = 0; i < count; i++)
            cells.add(CELL);
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();

            PayloadCarryingRpcController pcrc = new PayloadCarryingRpcController(CellUtil.createCellScanner(cells));

            BlockingRpcChannel channel = client.createBlockingRpcChannel(
                    ServerName.valueOf(address.getHostName(), address.getPort(), System.currentTimeMillis()),
                    User.getCurrent(), 0);

            channel.callBlockingMethod(md, pcrc, param, md.getOutputType().toProto());

            CellScanner cellScanner = pcrc.cellScanner();

            int index = 0;
            while (cellScanner.advance()) {
                assertTrue(CELL.equals(cellScanner.current()));
                index++;
            }
            assertEquals(count, index);
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    @Test
    public void testRTEDuringConnectionSetup() throws Exception {
        Configuration conf = HBaseConfiguration.create();
        SocketFactory spyFactory = spy(NetUtils.getDefaultSocketFactory(conf));
        Mockito.doAnswer(new Answer<Socket>() {
            @Override
            public Socket answer(InvocationOnMock invocation) throws Throwable {
                Socket s = spy((Socket) invocation.callRealMethod());
                doThrow(new RuntimeException("Injected fault")).when(s).setSoTimeout(anyInt());
                return s;
            }
        }).when(spyFactory).createSocket();

        TestRpcServer rpcServer = new TestRpcServer();
        RpcClientImpl client = new RpcClientImpl(conf, HConstants.CLUSTER_ID_DEFAULT, spyFactory);
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();
            client.call(null, md, param, null, User.getCurrent(), address);
            fail("Expected an exception to have been thrown!");
        } catch (Exception e) {
            LOG.info("Caught expected exception: " + e.toString());
            assertTrue(StringUtils.stringifyException(e).contains("Injected fault"));
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    @Test
    public void testRTEDuringAsyncBlockingConnectionSetup() throws Exception {
        Configuration conf = HBaseConfiguration.create();

        TestRpcServer rpcServer = new TestRpcServer();
        AsyncRpcClient client = new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null,
                new ChannelInitializer<SocketChannel>() {

                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addFirst(new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
                                    throws Exception {
                                promise.setFailure(new RuntimeException("Injected fault"));
                            }
                        });
                    }
                });
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();

            BlockingRpcChannel channel = client.createBlockingRpcChannel(
                    ServerName.valueOf(address.getHostName(), address.getPort(), System.currentTimeMillis()),
                    User.getCurrent(), 0);

            channel.callBlockingMethod(md, new PayloadCarryingRpcController(), param, md.getOutputType().toProto());

            fail("Expected an exception to have been thrown!");
        } catch (Exception e) {
            LOG.info("Caught expected exception: " + e.toString());
            assertTrue(StringUtils.stringifyException(e).contains("Injected fault"));
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    @Test
    public void testRTEDuringAsyncConnectionSetup() throws Exception {
        Configuration conf = HBaseConfiguration.create();

        TestRpcServer rpcServer = new TestRpcServer();
        AsyncRpcClient client = new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null,
                new ChannelInitializer<SocketChannel>() {

                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addFirst(new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
                                    throws Exception {
                                promise.setFailure(new RuntimeException("Injected fault"));
                            }
                        });
                    }
                });
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();

            RpcChannel channel = client.createRpcChannel(
                    ServerName.valueOf(address.getHostName(), address.getPort(), System.currentTimeMillis()),
                    User.getCurrent(), 0);

            final AtomicBoolean done = new AtomicBoolean(false);

            PayloadCarryingRpcController controller = new PayloadCarryingRpcController();
            controller.notifyOnFail(new RpcCallback<IOException>() {
                @Override
                public void run(IOException e) {
                    done.set(true);
                    LOG.info("Caught expected exception: " + e.toString());
                    assertTrue(StringUtils.stringifyException(e).contains("Injected fault"));
                }
            });

            channel.callMethod(md, controller, param, md.getOutputType().toProto(), new RpcCallback<Message>() {
                @Override
                public void run(Message parameter) {
                    done.set(true);
                    fail("Expected an exception to have been thrown!");
                }
            });

            TEST_UTIL.waitFor(1000, new Waiter.Predicate<Exception>() {
                @Override
                public boolean evaluate() throws Exception {
                    return done.get();
                }
            });
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    @Test
    public void testAsyncConnectionSetup() throws Exception {
        Configuration conf = HBaseConfiguration.create();

        TestRpcServer rpcServer = new TestRpcServer();
        AsyncRpcClient client = new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null);
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();

            RpcChannel channel = client.createRpcChannel(
                    ServerName.valueOf(address.getHostName(), address.getPort(), System.currentTimeMillis()),
                    User.getCurrent(), 0);

            final AtomicBoolean done = new AtomicBoolean(false);

            channel.callMethod(md, new PayloadCarryingRpcController(), param, md.getOutputType().toProto(),
                    new RpcCallback<Message>() {
                        @Override
                        public void run(Message parameter) {
                            done.set(true);
                        }
                    });

            TEST_UTIL.waitFor(1000, new Waiter.Predicate<Exception>() {
                @Override
                public boolean evaluate() throws Exception {
                    return done.get();
                }
            });
        } finally {
            client.close();
            rpcServer.stop();
        }
    }

    /** Tests that the rpc scheduler is called when requests arrive. */
    @Test
    public void testRpcScheduler() throws IOException, InterruptedException {
        RpcScheduler scheduler = spy(new FifoRpcScheduler(CONF, 1));
        RpcServer rpcServer = new TestRpcServer(scheduler);
        verify(scheduler).init((RpcScheduler.Context) anyObject());
        RpcClientImpl client = new RpcClientImpl(CONF, HConstants.CLUSTER_ID_DEFAULT);
        try {
            rpcServer.start();
            verify(scheduler).start();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();
            for (int i = 0; i < 10; i++) {
                client.call(new PayloadCarryingRpcController(CellUtil.createCellScanner(ImmutableList.of(CELL))),
                        md, param, md.getOutputType().toProto(), User.getCurrent(), rpcServer.getListenerAddress());
            }
            verify(scheduler, times(10)).dispatch((CallRunner) anyObject());
        } finally {
            rpcServer.stop();
            verify(scheduler).stop();
        }
    }

    /**
     * Tests that the rpc scheduler is called when requests arrive.
     */
    @Test
    public void testRpcSchedulerAsync() throws IOException, InterruptedException, ServiceException {
        RpcScheduler scheduler = spy(new FifoRpcScheduler(CONF, 1));
        RpcServer rpcServer = new TestRpcServer(scheduler);
        verify(scheduler).init((RpcScheduler.Context) anyObject());
        AbstractRpcClient client = new AsyncRpcClient(CONF, HConstants.CLUSTER_ID_DEFAULT, null);
        try {
            rpcServer.start();
            verify(scheduler).start();
            MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
            EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();
            ServerName serverName = ServerName.valueOf(rpcServer.getListenerAddress().getHostName(),
                    rpcServer.getListenerAddress().getPort(), System.currentTimeMillis());

            for (int i = 0; i < 10; i++) {
                BlockingRpcChannel channel = client.createBlockingRpcChannel(serverName, User.getCurrent(), 0);

                channel.callBlockingMethod(md,
                        new PayloadCarryingRpcController(CellUtil.createCellScanner(ImmutableList.of(CELL))), param,
                        md.getOutputType().toProto());
            }
            verify(scheduler, times(10)).dispatch((CallRunner) anyObject());
        } finally {
            rpcServer.stop();
            verify(scheduler).stop();
        }
    }

    public static void main(String[] args)
            throws IOException, SecurityException, NoSuchMethodException, InterruptedException {
        if (args.length != 2) {
            System.out.println("Usage: TestIPC <CYCLES> <CELLS_PER_CYCLE>");
            return;
        }
        // ((Log4JLogger)HBaseServer.LOG).getLogger().setLevel(Level.INFO);
        // ((Log4JLogger)HBaseClient.LOG).getLogger().setLevel(Level.INFO);
        int cycles = Integer.parseInt(args[0]);
        int cellcount = Integer.parseInt(args[1]);
        Configuration conf = HBaseConfiguration.create();
        TestRpcServer rpcServer = new TestRpcServer();
        MethodDescriptor md = SERVICE.getDescriptorForType().findMethodByName("echo");
        EchoRequestProto param = EchoRequestProto.newBuilder().setMessage("hello").build();
        RpcClientImpl client = new RpcClientImpl(conf, HConstants.CLUSTER_ID_DEFAULT);
        KeyValue kv = KeyValueUtil.ensureKeyValue(BIG_CELL);
        Put p = new Put(kv.getRow());
        for (int i = 0; i < cellcount; i++) {
            p.add(kv);
        }
        RowMutations rm = new RowMutations(kv.getRow());
        rm.add(p);
        try {
            rpcServer.start();
            InetSocketAddress address = rpcServer.getListenerAddress();
            long startTime = System.currentTimeMillis();
            User user = User.getCurrent();
            for (int i = 0; i < cycles; i++) {
                List<CellScannable> cells = new ArrayList<CellScannable>();
                // Message param = RequestConverter.buildMultiRequest(HConstants.EMPTY_BYTE_ARRAY, rm);
                ClientProtos.RegionAction.Builder builder = RequestConverter.buildNoDataRegionAction(
                        HConstants.EMPTY_BYTE_ARRAY, rm, cells, RegionAction.newBuilder(),
                        ClientProtos.Action.newBuilder(), MutationProto.newBuilder());
                builder.setRegion(RegionSpecifier.newBuilder().setType(RegionSpecifierType.REGION_NAME)
                        .setValue(ByteString.copyFrom(HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes())));
                if (i % 100000 == 0) {
                    LOG.info("" + i);
                    // Uncomment this for a thread dump every so often.
                    // ReflectionUtils.printThreadInfo(new PrintWriter(System.out),
                    //  "Thread dump " + Thread.currentThread().getName());
                }
                PayloadCarryingRpcController pcrc = new PayloadCarryingRpcController(
                        CellUtil.createCellScanner(cells));
                Pair<Message, CellScanner> response = client.call(pcrc, md, builder.build(), param, user, address);
                /*
                int count = 0;
                while (p.getSecond().advance()) {
                  count++;
                }
                assertEquals(cells.size(), count);*/
            }
            LOG.info("Cycled " + cycles + " time(s) with " + cellcount + " cell(s) in "
                    + (System.currentTimeMillis() - startTime) + "ms");
        } finally {
            client.close();
            rpcServer.stop();
        }
    }
}