com.wmz7year.thrift.pool.BasicAbstractTest.java Source code

Java tutorial

Introduction

Here is the source code for com.wmz7year.thrift.pool.BasicAbstractTest.java

Source

/**
 *              Copyright 2015 Jiang Wei
 *
 *    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.
 */

package com.wmz7year.thrift.pool;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.thrift.TException;
import org.apache.thrift.TMultiplexedProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.server.TThreadPoolServer.Args;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wmz7year.thrift.pool.config.ThriftServerInfo;
import com.wmz7year.thrift.pool.example.Example;
import com.wmz7year.thrift.pool.example.Example.Iface;
import com.wmz7year.thrift.pool.example.Example.Processor;
import com.wmz7year.thrift.pool.example.Other;

import junit.framework.TestCase;

/**
 * <br>
 * ??<br>
 * ?N?<br>
 * ???
 * 
 * @Title: BasicAbstractTest.java
 * @Package com.wmz7year.thrift.pool.config
 * @author jiangwei (ydswcy513@gmail.com)
 * @date 20151119 ?1:23:04
 * @version V1.0
 */
public abstract class BasicAbstractTest extends TestCase {
    protected static final Logger logger = LoggerFactory.getLogger(BasicAbstractTest.class);
    /**
     * ???
     */
    protected static final int MIN_PORT = 40000;
    /**
     * ??
     */
    protected static final int MAX_PORT = 41000;
    /**
     * ?
     */
    protected static final String LOACLHOST = "127.0.0.1";

    /**
     * ??
     */
    private static final long DFLT_TEST_TIMEOUT = 5 * 60 * 1000;

    /**
     * ????
     */
    private boolean stopErr;

    /**
     * ?
     */
    private static long ts = System.currentTimeMillis();

    /**
     * ??
     */
    private List<TServer> servers = new ArrayList<TServer>();

    /**
     * ?
     * 
     * @throws Exception
     *             ?
     */
    protected abstract void beforeTest() throws Exception;

    /**
     * ??
     * 
     * @throws Exception
     *             ?
     */
    protected abstract void afterTest() throws Exception;

    /*
     * @see junit.framework.TestCase#setUp()
     */
    @Override
    protected void setUp() throws Exception {
        stopErr = false;

        try {
            beforeTest();
        } catch (Exception t) {
            t.printStackTrace();

            tearDown();
        }

        ts = System.currentTimeMillis();
    }

    /**
     * ??
     * 
     * @throws Throwable
     *             ?
     */
    private void runTestInternal() throws Throwable {
        super.runTest();
    }

    /*
     * @see junit.framework.TestCase#runTest()
     */
    @Override
    protected void runTest() throws Throwable {
        final AtomicReference<Throwable> ex = new AtomicReference<Throwable>();

        Thread runner = new Thread("test-runner") {
            @Override
            public void run() {
                try {
                    runTestInternal();
                } catch (Throwable e) {
                    ex.set(e);
                }
            }
        };

        runner.start();

        runner.join(isDebug() ? 0 : DFLT_TEST_TIMEOUT);

        if (runner.isAlive()) {
            throw new TimeoutException("?? [??" + getName()
                    + " " + DFLT_TEST_TIMEOUT + "]");
        }

        Throwable t = ex.get();
        if (t != null) {
            throw t;
        }

        assert !stopErr : "???";
    }

    /*
     * @see junit.framework.TestCase#tearDown()
     */
    @Override
    protected void tearDown() throws Exception {
        long dur = System.currentTimeMillis() - ts;
        logger.info("? ??" + getName() + "  ?" + dur + "ms");

        // ?
        afterTest();

        // ?
        stopAllServers();
    }

    /**
     * thrift?
     */
    protected void stopAllServers() {
        for (TServer tServer : servers) {
            tServer.stop();
        }
    }

    /**
     * ?debug??<br>
     * ??-DDEBUG??
     * 
     * @return truedebug? false?debug?
     */
    protected boolean isDebug() {
        return System.getProperty("DEBUG") != null;
    }

    /**
     * ??<br>
     * 
     * 
     * @param count
     *            ???
     * @return ???
     */
    protected List<ThriftServerInfo> startServers(int count) throws Exception {
        List<ThriftServerInfo> result = new ArrayList<ThriftServerInfo>();
        for (int i = 0; i < count; i++) {
            try {
                ThriftServerInfo startServer = startServer();
                result.add(startServer);
            } catch (Throwable e) {
                continue;
            }
        }
        return result;
    }

    /**
     * ???
     * 
     * @param count
     *            ???
     * @return ???
     */
    protected List<ThriftServerInfo> startMulitServiceServers(int count) throws Exception {
        List<ThriftServerInfo> result = new ArrayList<ThriftServerInfo>();
        for (int i = 0; i < count; i++) {
            try {
                ThriftServerInfo startServer = startMulitServiceServer();
                result.add(startServer);
            } catch (Throwable e) {
                continue;
            }
        }
        return result;
    }

    protected ThriftServerInfo startServer() throws Throwable {
        // ???
        final int port = choseListenPort();
        ThriftServerInfo serverInfo = new ThriftServerInfo(LOACLHOST, port);
        final AtomicReference<Throwable> ex = new AtomicReference<Throwable>();

        Thread runner = new Thread("thrift-server-starter") {
            @Override
            public void run() {
                try {
                    TServerTransport serverTransport = new TServerSocket(port);
                    Factory proFactory = new TBinaryProtocol.Factory();
                    Processor<Iface> processor = new Example.Processor<Example.Iface>(new Example.Iface() {

                        @Override
                        public void pong() throws TException {
                            logger.info("pong");
                        }

                        @Override
                        public void ping() throws TException {
                            logger.info("ping");
                        }
                    });
                    Args thriftArgs = new Args(serverTransport);
                    thriftArgs.processor(processor);
                    thriftArgs.protocolFactory(proFactory);
                    TServer tserver = new TThreadPoolServer(thriftArgs);
                    servers.add(tserver);
                    logger.info("???" + port);
                    tserver.serve();
                } catch (TTransportException e) {
                    logger.error("thrift??", e);
                    ex.set(e);
                }
            }
        };

        runner.start();

        Throwable throwable = ex.get();
        if (throwable != null) {
            throw throwable;
        }
        // ??
        Thread.sleep(1000);
        return serverInfo;
    }

    protected ThriftServerInfo startMulitServiceServer() throws Throwable {
        // ???
        final int port = choseListenPort();
        ThriftServerInfo serverInfo = new ThriftServerInfo(LOACLHOST, port);
        final AtomicReference<Throwable> ex = new AtomicReference<Throwable>();
        // TODO
        Thread runner = new Thread("thrift-server-starter") {
            @Override
            public void run() {
                try {
                    TMultiplexedProcessor processor = new TMultiplexedProcessor();
                    TServerTransport serverTransport = new TServerSocket(port);
                    Factory proFactory = new TBinaryProtocol.Factory();

                    processor.registerProcessor("example",
                            new Example.Processor<Example.Iface>(new Example.Iface() {

                                @Override
                                public void pong() throws TException {
                                    logger.info("example pong");
                                }

                                @Override
                                public void ping() throws TException {
                                    logger.info("example ping");
                                }
                            }));

                    processor.registerProcessor("other", new Other.Processor<Other.Iface>(new Other.Iface() {

                        @Override
                        public void pong() throws TException {
                            logger.info("other pong");
                        }

                        @Override
                        public void ping() throws TException {
                            logger.info("other ping");
                        }
                    }));
                    Args thriftArgs = new Args(serverTransport);
                    thriftArgs.processor(processor);
                    thriftArgs.protocolFactory(proFactory);
                    TServer tserver = new TThreadPoolServer(thriftArgs);
                    servers.add(tserver);
                    logger.info("???" + port);
                    tserver.serve();
                } catch (TTransportException e) {
                    logger.error("thrift??", e);
                    ex.set(e);
                }
            }
        };

        runner.start();

        Throwable throwable = ex.get();
        if (throwable != null) {
            throw throwable;
        }
        // ??
        Thread.sleep(1000);
        return serverInfo;
    }

    /**
     * ??? return ???
     */
    private int choseListenPort() {
        for (int port = MIN_PORT; port < MAX_PORT; port++) {
            if (checkPortNotInUse(port)) {
                return port;
            }
        }
        return 0;
    }

    /**
     * ??
     * 
     * @param port
     *            ??
     * @return true false
     */
    private boolean checkPortNotInUse(int port) {
        try {
            new ServerSocket(port).close();
            return true;
        } catch (IOException e) {
            return false;
        }
    }

}