Java tutorial
/** * 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; } } }