Java tutorial
/** * Project: ocean.client.java.basic * * File Created at 2011-10-17 * $Id: AlibabaClientReactor.java 311300 2013-12-23 06:15:28Z yichun.wangyc $ * * Copyright 2008 Alibaba.com Croporation Limited. * All rights reserved. * * This software is the confidential and proprietary information of * Alibaba Company. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Alibaba.com. */ package com.alibaba.openapi.client.rpc; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetSocketAddress; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpException; import org.apache.http.HttpVersion; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.nio.NHttpConnection; import org.apache.http.nio.protocol.AsyncNHttpClientHandler; import org.apache.http.nio.protocol.EventListener; import org.apache.http.nio.reactor.ConnectingIOReactor; import org.apache.http.nio.reactor.IOEventDispatch; import org.apache.http.nio.reactor.IOReactorException; import org.apache.http.nio.reactor.SessionRequest; import org.apache.http.nio.util.ByteBufferAllocator; import org.apache.http.nio.util.HeapByteBufferAllocator; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.BasicHttpProcessor; import org.apache.http.protocol.HttpProcessor; import org.apache.http.protocol.RequestContent; import org.apache.http.protocol.RequestTargetHost; import org.apache.http.protocol.RequestUserAgent; import com.alibaba.openapi.client.FutureCallback; import com.alibaba.openapi.client.Request; import com.alibaba.openapi.client.Response; import com.alibaba.openapi.client.exception.InvokeConnectException; import com.alibaba.openapi.client.exception.InvokeTimeoutException; import com.alibaba.openapi.client.exception.OceanException; import com.alibaba.openapi.client.policy.ClientPolicy; import com.alibaba.openapi.client.policy.RequestPolicy; import com.alibaba.openapi.client.rpc.io.AutoSSLClientIOEventDispatch; import com.alibaba.openapi.client.rpc.io.RequestAcceptEncoding; import com.alibaba.openapi.client.rpc.io.SessionRequestCallbackTrigger; import com.alibaba.openapi.client.util.LoggerHelper; import com.alibaba.openapi.client.util.NamedThreadFactory; /** * Comment of AlibabaClientReactor * ??,I/O???I/OI/O? * @author jade */ public class AlibabaClientReactor implements Callable<Integer> { private ConnectingIOReactor ioReactor; private IOEventDispatch ioEventDispatch; private ExecutorService executorService; private Future<Integer> workerFuture; private ClientPolicy policy; public Integer call() throws Exception { try { System.out.println("call...Starts the reactor and initiates the dispatch"); //??,I/O???I/OI/O? ioReactor.execute(ioEventDispatch); } catch (InterruptedIOException ex) { LoggerHelper.getClientLogger().warning("AlibabaClientReactor Interrupted"); } catch (IOException e) { LoggerHelper.getClientLogger().warning("AlibabaClientReactor I/O error: " + e.getMessage()); e.printStackTrace(); } LoggerHelper.getClientLogger().finer("AlibabaClientReactor Shutdown"); return null; } protected HttpParams getHttpParams() { HttpParams params = new BasicHttpParams(); params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000) .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000) .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, policy.getContentCharset()); HttpConnectionParams.setTcpNoDelay(params, true); HttpConnectionParams.setSocketBufferSize(params, 8192); //HttpConnectionParams.setSoTimeout(params, 0); HttpProtocolParams.setUserAgent(params, "OceanClient/0.1"); return params; } public synchronized void start(ClientPolicy policy) throws IOReactorException, NoSuchAlgorithmException, KeyManagementException { if (workerFuture != null) { throw new IllegalStateException("[AlibabaClientReactor]is already started"); } LoggerHelper.getClientLogger().finer("[AlibabaClientReactor START]-- start OK"); this.policy = policy; //Initialize HTTP processor HttpParams params = getHttpParams(); //System.out.println("create IOEventDispatch..."); createIOEventDispatch(policy, params); //System.out.println("ioReactor init..."); ioReactor = new DefaultConnectingIOReactor(1, params); executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("AlibabaClientReactor", true)); //System.out.println("AlibabaClientReactor submit..."); workerFuture = executorService.submit(this); } private void createIOEventDispatch(ClientPolicy policy, HttpParams params) throws NoSuchAlgorithmException, KeyManagementException { HttpProcessor httpproc = createHttpProcessor(); ByteBufferAllocator allocator = new HeapByteBufferAllocator(); ////HTTP I/O?I/O???I/O?HTTP???NHttpClientHandlerNHttpServiceHandler?HTTP??HTTP???(handler). AsyncNHttpClientHandler handler = new AsyncNHttpClientHandler(httpproc, new AliNHttpRequstExecutionHandler(new ProtocolProvider(policy), allocator), new DefaultConnectionReuseStrategy(), allocator, params); // BufferingHttpClientHandler handler = new BufferingHttpClientHandler(httpproc, new MyHttpRequestExecutionHandler(), // new DefaultConnectionReuseStrategy(), params); handler.setEventListener(new EventLogger()); SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException { } public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException { } } }, new SecureRandom()); sslcontext.getClientSessionContext().setSessionCacheSize(200); sslcontext.getClientSessionContext().setSessionTimeout(30000); //dispatchIOhandler ioEventDispatch = new AutoSSLClientIOEventDispatch(handler, sslcontext, params); } protected BasicHttpProcessor createHttpProcessor() { BasicHttpProcessor httpproc = new BasicHttpProcessor(); // Required protocol interceptors httpproc.addInterceptor(new RequestContent()); httpproc.addInterceptor(new RequestTargetHost()); // Recommended protocol interceptors httpproc.addInterceptor(new RequestUserAgent()); httpproc.addInterceptor(new RequestAcceptEncoding()); return httpproc; } public synchronized void shutdown() throws IOException { if (workerFuture == null) { LoggerHelper.getClientLogger().warning("[AlibabaClientReactor]is already shutdown"); } else { if (workerFuture.isCancelled()) { LoggerHelper.getClientLogger().warning("[AlibabaClientReactor] worker is already cancelled"); } else if (workerFuture.isDone()) { LoggerHelper.getClientLogger().warning("[AlibabaClientReactor] worker is already done"); } else { workerFuture.cancel(true); } } workerFuture = null; if (executorService != null) { System.out.println("AlibabaClientReactor executorService will shutdown..."); executorService.shutdownNow(); } executorService = null; LoggerHelper.getClientLogger().finer("[AlibabaClientReactor SHUTDONW]-- shutdown OK"); ioReactor.shutdown(); } public <T> Future<T> send(Request request, Class<T> resultType, ClientPolicy clientPolicy, final RequestPolicy requestPolicy, FutureCallback<T> callback) { final InvokeContext context = new InvokeContext(); context.setRequest(request); context.setPolicy(requestPolicy); context.setCallback(callback); context.setResultType(resultType); int serverPort = requestPolicy.isUseHttps() ? clientPolicy.getHttpsPort() : clientPolicy.getHttpPort(); LoggerHelper.getClientLogger().finer( "Use " + (clientPolicy.isUseHttps() ? "https" : "http") + " connect and create SessionRequest"); //SessionRequestCallback?? //SessionRequest?? final SessionRequest req = ioReactor.connect( new InetSocketAddress(clientPolicy.getServerHost(), serverPort), null, context, new SessionRequestCallbackTrigger()); return new Future<T>() { private boolean cancelled = false; public boolean cancel(boolean mayInterruptIfRunning) { if (req.isCompleted() || cancelled) { return false; } cancelled = true; req.cancel(); context.completed(); return true; } public boolean isCancelled() { return cancelled; } public boolean isDone() { return context.isCompleted() || cancelled; } public T get() throws InterruptedException, ExecutionException { context.waitForComplete(); return _get(); } public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { context.waitForComplete(timeout, unit); return _get(); } @SuppressWarnings("unchecked") private T _get() throws ExecutionException { Response response = ((InvokeContext) req.getAttachment()).getResponse(); Throwable targetException = response.getException(); if (targetException != null) { if (requestPolicy.getErrorHandler() != null && targetException instanceof OceanException) { requestPolicy.getErrorHandler().handle((OceanException) targetException); } throw new ExecutionException(targetException.getMessage(), targetException); } return (T) response.getResult(); } }; } static class EventLogger implements EventListener { public final static String CONTEXT_ATTACHMENT = "context.attachment"; public void connectionOpen(final NHttpConnection conn) { LoggerHelper.getClientLogger().finer("AliClient Connection open: " + conn); } public void connectionTimeout(final NHttpConnection conn) { LoggerHelper.getClientLogger().warning("AliClient Connection timed out: " + conn); InvokeContext context = (InvokeContext) conn.getContext().getAttribute(CONTEXT_ATTACHMENT); context.completed(); context.failed(new InvokeTimeoutException("AliClient Connection timed out.")); } public void connectionClosed(final NHttpConnection conn) { LoggerHelper.getClientLogger().finer("AliClient Connection closed: " + conn); } public void fatalIOException(final IOException ex, final NHttpConnection conn) { InvokeContext context = (InvokeContext) conn.getContext().getAttribute(CONTEXT_ATTACHMENT); context.completed(); context.failed(new InvokeConnectException("AliClient I/O error: ", ex)); LoggerHelper.getClientLogger().warning("AliClient I/O error: " + ex.getMessage() + ", conn: " + conn); } public void fatalProtocolException(final HttpException ex, final NHttpConnection conn) { LoggerHelper.getClientLogger().warning("AliClient HTTP error." + ex.getMessage() + ", conn: " + conn); InvokeContext context = (InvokeContext) conn.getContext().getAttribute(CONTEXT_ATTACHMENT); context.completed(); context.failed(new InvokeConnectException("AliClient HTTP error.", ex)); } } }