Java tutorial
/* * Copyright 2008 biaoping.yin * * 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 org.frameworkset.spi.remote.http; import java.io.IOException; import java.net.InetSocketAddress; import java.util.List; import javax.net.ssl.SSLContext; import org.apache.http.HttpException; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.nio.DefaultServerIOEventDispatch; import org.apache.http.impl.nio.SSLServerIOEventDispatch; import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor; import org.apache.http.impl.nio.reactor.ExceptionEvent; import org.apache.http.nio.NHttpConnection; import org.apache.http.nio.NHttpServiceHandler; import org.apache.http.nio.protocol.BufferingHttpServiceHandler; import org.apache.http.nio.protocol.EventListener; import org.apache.http.nio.reactor.IOEventDispatch; import org.apache.http.nio.reactor.IOReactorException; import org.apache.http.nio.reactor.IOReactorStatus; import org.apache.http.nio.reactor.ListenerEndpoint; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpProcessor; import org.apache.http.protocol.HttpExpectationVerifier; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.protocol.ResponseConnControl; import org.apache.http.protocol.ResponseContent; import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.frameworkset.spi.ApplicationContext; import org.frameworkset.spi.assemble.ProMap; import org.frameworkset.spi.remote.RPCAddress; import org.frameworkset.spi.remote.SSLHelper; import org.frameworkset.spi.remote.Target; import org.frameworkset.spi.remote.mina.client.ClinentTransport; /** * <p> * Title: HttpServer.java * </p> * <p> * Description: * </p> * <p> * bboss workgroup * </p> * <p> * Copyright (c) 2008 * </p> * * @Date 2010-9-2 * @author biaoping.yin * @version 1.0 */ public class HttpServer { private DefaultListeningIOReactor ioReactor; private ProMap params; HttpParams serverParams = null; private String ip; private int port; private boolean enablessl; private int workerCount = 4; private volatile IOReactorThread thread; private ListenerEndpoint endpoint; // private volatile RequestCount requestCount; public HttpServer(ProMap params) throws IOException { super(); this.params = params; this.ip = this.params.getString("connection.bind.ip", "localhost"); this.port = this.params.getInt("connection.bind.port", 8080); enablessl = this.params.getBoolean("enablessl", false); workerCount = this.params.getInt("http.workerCount", 4); this.localAddress = new RPCAddress(this.ip, port, null, enablessl ? Target.BROADCAST_TYPE_HTTPS : Target.BROADCAST_TYPE_HTTP); } // // public void setRequestCount(final RequestCount requestCount) { // // this.requestCount = requestCount; // // } // // public void setExceptionHandler( // final IOReactorExceptionHandler exceptionHandler) { // this.ioReactor.setExceptionHandler(exceptionHandler); // } private void execute(IOEventDispatch ioEventDispatch) throws IOException { this.ioReactor.execute(ioEventDispatch); } public ListenerEndpoint getListenerEndpoint() { return this.endpoint; } public void setEndpoint(ListenerEndpoint endpoint) { this.endpoint = endpoint; } public IOReactorStatus getStatus() { return this.ioReactor.getStatus(); } public List<ExceptionEvent> getAuditLog() { return this.ioReactor.getAuditLog(); } public void join(long timeout) throws InterruptedException { if (this.thread != null) { this.thread.join(timeout); } } public Exception getException() { if (this.thread != null) { return this.thread.getException(); } else { return null; } } private void startHttp() throws IOException { try { this.ioReactor = new DefaultListeningIOReactor(workerCount, serverParams); EventListener serverEventListener = new EventListener() { // @Override public void connectionClosed(NHttpConnection conn) { // closedServerConns.decrement(); // super.connectionClosed(conn); // System.out.println("connectionClosed:" + conn); } public void connectionOpen(NHttpConnection conn) { // System.out.println("connectionOpen:" + conn); } public void connectionTimeout(NHttpConnection conn) { System.out.println("connectionTimeout:" + conn); } public void fatalIOException(IOException ex, NHttpConnection conn) { // System.out.println("fatalIOException:" + conn); ex.printStackTrace(); } public void fatalProtocolException(HttpException ex, NHttpConnection conn) { // System.out.println("fatalProtocolException:" + conn); ex.printStackTrace(); } }; final NHttpServiceHandler serviceHandler = createHttpServiceHandler(HttpUtil.getHttpBaseRPCIOHandler(), null, serverEventListener); this.endpoint = this.ioReactor.listen(new InetSocketAddress(ip, port)); IOEventDispatch ioEventDispatch = new DefaultServerIOEventDispatch(serviceHandler, serverParams); // this.execute(serviceHandler, ioEventDispatch); this.thread = new IOReactorThread(ioEventDispatch); this.thread.start(); try { thread.join(1000); this.started = true; } catch (InterruptedException e) { e.printStackTrace(); } } catch (IOReactorException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void startHttps() throws Exception { try { this.ioReactor = new DefaultListeningIOReactor(workerCount, serverParams); EventListener serverEventListener = new EventListener() { // @Override public void connectionClosed(NHttpConnection conn) { // closedServerConns.decrement(); // super.connectionClosed(conn); // System.out.println("connectionClosed:" + conn); } public void connectionOpen(NHttpConnection conn) { // System.out.println("connectionOpen:" + conn); } public void connectionTimeout(NHttpConnection conn) { System.out.println("connectionTimeout:" + conn); } public void fatalIOException(IOException ex, NHttpConnection conn) { // System.out.println("fatalIOException:" + conn); ex.printStackTrace(); } public void fatalProtocolException(HttpException ex, NHttpConnection conn) { // System.out.println("fatalProtocolException:" + conn); ex.printStackTrace(); } }; final NHttpServiceHandler serviceHandler = createHttpServiceHandler(HttpUtil.getHttpBaseRPCIOHandler(), null, serverEventListener); this.endpoint = this.ioReactor.listen(new InetSocketAddress(ip, port)); ProMap ssls = ApplicationContext.getApplicationContext().getMapProperty("rpc.protocol.http.ssl.server"); if (ssls == null) { throw new Exception( "?ssl? rpc.protocol.http.ssl.server ?org/frameworkset/spi/manager-rpc-http.xml??"); } String keyStore = ssls.getString("keyStore"); String keyStorePassword = ssls.getString("keyStorePassword"); String trustStore = ssls.getString("trustStore"); String trustStorePassword = ssls.getString("trustStorePassword"); SSLContext sslcontext = SSLHelper.createSSLContext(keyStore, keyStorePassword, trustStore, trustStorePassword); IOEventDispatch ioEventDispatch = new SSLServerIOEventDispatch(serviceHandler, sslcontext, serverParams); // IOEventDispatch ioEventDispatch = new DefaultServerIOEventDispatch( // serviceHandler, serverParams); // this.execute(serviceHandler, ioEventDispatch); this.thread = new IOReactorThread(ioEventDispatch); this.thread.start(); try { thread.join(1000); this.started = true; } catch (InterruptedException e) { e.printStackTrace(); } // ClassLoader cl = this.getClass().getClassLoader(); // URL url = cl.getResource("test.keystore"); // KeyStore keystore = KeyStore.getInstance("jks"); // keystore.load(url.openStream(), "nopassword".toCharArray()); // KeyManagerFactory kmfactory = KeyManagerFactory.getInstance( // KeyManagerFactory.getDefaultAlgorithm()); // kmfactory.init(keystore, "nopassword".toCharArray()); // KeyManager[] keymanagers = kmfactory.getKeyManagers(); // SSLContext sslcontext = SSLContext.getInstance("TLS"); // sslcontext.init(keymanagers, null, null); // // Set up request handlers // HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry(); // reqistry.register("*", new HttpFileHandler(args[0])); // // handler.setHandlerResolver(reqistry); // // // Provide an event logger // handler.setEventListener(new EventLogger()); // // // // ListeningIOReactor ioReactor = new DefaultListeningIOReactor(2, params); // try { // ioReactor.listen(new InetSocketAddress(8080)); // ioReactor.execute(ioEventDispatch); // } catch (InterruptedIOException ex) { // System.err.println("Interrupted"); // } catch (IOException e) { // System.err.println("I/O error: " + e.getMessage()); // } // System.out.println("Shutdown"); } catch (IOReactorException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void start() { serverParams = new BasicHttpParams(); int so_timeout = this.params.getInt("http.socket.timeout", 30);//?? int SOCKET_BUFFER_SIZE = this.params.getInt("http.socket.buffer-size", 8 * 1024); boolean STALE_CONNECTION_CHECK = this.params.getBoolean("http.connection.stalecheck", false); boolean TCP_NODELAY = this.params.getBoolean("TCP_NODELAY", true); String ORIGIN_SERVER = this.params.getString("http.origin-server", "RPC-SERVER/1.1"); int CONNECTION_TIMEOUT = this.params.getInt("http.connection.timeout", 30); int httpsoLinger = this.params.getInt("http.soLinger", -1); serverParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, so_timeout * 1000) .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, SOCKET_BUFFER_SIZE) .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, STALE_CONNECTION_CHECK) .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, TCP_NODELAY) .setParameter(CoreProtocolPNames.ORIGIN_SERVER, ORIGIN_SERVER) .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIMEOUT * 1000) .setIntParameter(CoreConnectionPNames.SO_LINGER, httpsoLinger); if (!enablessl) { try { this.startHttp(); System.out.println("Http server is listenig at port " + port + ",ip is " + this.ip); System.out.println("Http server started."); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { this.startHttps(); System.out.println("Https server is listenig at port " + port + ",ip is " + this.ip); System.out.println("Https server started."); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (this.started) ApplicationContext.addShutdownHook(new ShutDownHttpServer(this)); } public void shutdown() throws IOException { this.ioReactor.shutdown(); this.started = false; try { join(500); } catch (InterruptedException ignore) { } } private class IOReactorThread extends Thread { private IOEventDispatch ioEventDispatch; private volatile Exception ex; public IOReactorThread(final IOEventDispatch ioEventDispatch) { super(); this.ioEventDispatch = ioEventDispatch; } @Override public void run() { try { execute(ioEventDispatch); } catch (Exception ex) { this.ex = ex; // if (requestCount != null) { // requestCount.failure(ex); // } } } public Exception getException() { return this.ex; } } private boolean started = false; private RPCAddress localAddress; public boolean validateAddress(RPCAddress address) { //??? return ClinentTransport.validateAddress(address); } private static HttpServer server; public static HttpServer getHttpServer() { if (server != null) return server; synchronized (HttpServer.class) { if (server != null) return server; server = (HttpServer) ApplicationContext.getApplicationContext().getBeanObject("rpc.http.server"); } return server; } private static class ShutDownHttpServer implements Runnable { HttpServer server; ShutDownHttpServer(HttpServer server) { this.server = server; } public void run() { server.stop(); } } public boolean started() { return this.started; } public void stop() { try { this.shutdown(); started = false; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public RPCAddress getLocalAddress() { // TODO Auto-generated method stub return this.localAddress; } // this.httpserver.start(serviceHandler); // ListenerEndpoint endpoint = this.server.getListenerEndpoint(); // endpoint.waitFor(); // InetSocketAddress serverAddress = (InetSocketAddress) // endpoint.getAddress(); // this.server.shutdown(); // closedServerConns.await(10000); protected NHttpServiceHandler createHttpServiceHandler(HttpRequestHandler requestHandler, HttpExpectationVerifier expectationVerifier, EventListener eventListener) { BasicHttpProcessor httpproc = new BasicHttpProcessor(); httpproc.addInterceptor(new ResponseDate()); httpproc.addInterceptor(new ResponseServer()); httpproc.addInterceptor(new ResponseContent()); httpproc.addInterceptor(new ResponseConnControl()); BufferingHttpServiceHandler serviceHandler = new BufferingHttpServiceHandler(httpproc, new DefaultHttpResponseFactory(), new DefaultConnectionReuseStrategy(), this.serverParams); serviceHandler.setHandlerResolver(new SimpleHttpRequestHandlerResolver(requestHandler)); serviceHandler.setExpectationVerifier(expectationVerifier); serviceHandler.setEventListener(eventListener); return serviceHandler; } public ProMap getParams() { return this.params; } }