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

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.hbase.ipc.TestAsyncIPC.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.assertTrue;
import static org.junit.Assert.fail;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CellScannable;
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.ServerName;
import org.apache.hadoop.hbase.Waiter;
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.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.testclassification.RPCTests;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.util.StringUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.google.protobuf.ByteString;
import com.google.protobuf.Descriptors.MethodDescriptor;
import com.google.protobuf.Message;
import com.google.protobuf.RpcCallback;
import com.google.protobuf.RpcChannel;

@RunWith(Parameterized.class)
@Category({ RPCTests.class, SmallTests.class })
public class TestAsyncIPC extends AbstractTestIPC {

    private static final Log LOG = LogFactory.getLog(TestAsyncIPC.class);

    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();

    @Parameters
    public static Collection<Object[]> parameters() {
        List<Object[]> paramList = new ArrayList<Object[]>();
        paramList.add(new Object[] { false, false });
        paramList.add(new Object[] { false, true });
        paramList.add(new Object[] { true, false });
        paramList.add(new Object[] { true, true });
        return paramList;
    }

    private final boolean useNativeTransport;

    private final boolean useGlobalEventLoopGroup;

    public TestAsyncIPC(boolean useNativeTransport, boolean useGlobalEventLoopGroup) {
        this.useNativeTransport = useNativeTransport;
        this.useGlobalEventLoopGroup = useGlobalEventLoopGroup;
    }

    private void setConf(Configuration conf) {
        conf.setBoolean(AsyncRpcClient.USE_NATIVE_TRANSPORT, useNativeTransport);
        conf.setBoolean(AsyncRpcClient.USE_NATIVE_TRANSPORT, useGlobalEventLoopGroup);
        if (useGlobalEventLoopGroup && AsyncRpcClient.GLOBAL_EVENT_LOOP_GROUP != null) {
            if (useNativeTransport
                    && !(AsyncRpcClient.GLOBAL_EVENT_LOOP_GROUP.getFirst() instanceof EpollEventLoopGroup)
                    || (!useNativeTransport
                            && !(AsyncRpcClient.GLOBAL_EVENT_LOOP_GROUP.getFirst() instanceof NioEventLoopGroup))) {
                AsyncRpcClient.GLOBAL_EVENT_LOOP_GROUP.getFirst().shutdownGracefully();
                AsyncRpcClient.GLOBAL_EVENT_LOOP_GROUP = null;
            }
        }
    }

    @Override
    protected AsyncRpcClient createRpcClientNoCodec(Configuration conf) {
        setConf(conf);
        return new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null) {

            @Override
            Codec getCodec() {
                return super.getCodec();
            }

        };
    }

    @Override
    protected AsyncRpcClient createRpcClient(Configuration conf) {
        setConf(conf);
        return new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null);
    }

    @Override
    protected AsyncRpcClient createRpcClientRTEDuringConnectionSetup(Configuration conf) {
        setConf(conf);
        return 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"));
                            }
                        });
                    }
                });
    }

    @Test
    public void testAsyncConnectionSetup() throws Exception {
        TestRpcServer rpcServer = new TestRpcServer();
        AsyncRpcClient client = createRpcClient(CONF);
        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();
        }
    }

    @Test
    public void testRTEDuringAsyncConnectionSetup() throws Exception {
        TestRpcServer rpcServer = new TestRpcServer();
        AsyncRpcClient client = createRpcClientRTEDuringConnectionSetup(CONF);
        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();
        }
    }

    public static void main(String[] args)
            throws IOException, SecurityException, NoSuchMethodException, InterruptedException {
        if (args.length != 2) {
            System.out.println("Usage: TestAsyncIPC <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();
        AsyncRpcClient client = new AsyncRpcClient(conf, HConstants.CLUSTER_ID_DEFAULT, null);
        KeyValue kv = BIG_CELL;
        Put p = new Put(CellUtil.cloneRow(kv));
        for (int i = 0; i < cellcount; i++) {
            p.add(kv);
        }
        RowMutations rm = new RowMutations(CellUtil.cloneRow(kv));
        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();
        }
    }
}