SimpleAxisServer.java |
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Axis" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.jboss.axis.transport.http; import org.jboss.axis.server.AxisServer; import org.jboss.axis.session.Session; import org.jboss.axis.session.SimpleSession; import org.jboss.axis.utils.Messages; import org.jboss.axis.utils.Options; import org.jboss.logging.Logger; import java.net.MalformedURLException; import java.net.ServerSocket; import java.net.Socket; import java.util.Hashtable; /** * This is a simple implementation of an HTTP server for processing * SOAP requests via Apache's xml-axis. This is not intended for production * use. Its intended uses are for demos, debugging, and performance * profiling. * * @author Sam Ruby (ruby@us.ibm.com) * @author Rob Jellinghaus (robj@unrealities.com) */ public class SimpleAxisServer implements Runnable { private static Logger log = Logger.getLogger(SimpleAxisServer.class.getName()); // session state. // This table maps session keys (random numbers) to SimpleAxisSession objects. // // There is NO CLEANUP of this table at present, and if clients are not // passing cookies, then a new session will be created for *every* request. // This is the biggest impediment to any kind of real SimpleAxisServer use. // So, if this becomes objectionable, we will implement some simpleminded // cleanup (perhaps just a cap on max # of sessions, and some kind of LRU // cleanup policy). private Hashtable sessions = new Hashtable(); // Are we doing threads? private static boolean doThreads = true; // Are we doing sessions? // Set this to false if you don't want any session overhead. private static boolean doSessions = true; protected boolean isSessionUsed() { return doSessions; } public void setDoThreads(boolean value) { doThreads = value; } public boolean getDoThreads() { return doThreads; } protected Session createSession(String cooky) { // is there a session already? Session session = null; if (sessions.containsKey(cooky)) { session = (Session)sessions.get(cooky); } else { // no session for this cooky, bummer session = new SimpleSession(); // ADD CLEANUP LOGIC HERE if needed sessions.put(cooky, session); } return session; } // What is our current session index? // This is a monotonically increasing, non-thread-safe integer // (thread safety not considered crucial here) public static int sessionIndex = 0; // Axis server (shared between instances) private static AxisServer myAxisServer = null; protected static synchronized AxisServer getAxisServer() { if (myAxisServer == null) { myAxisServer = new AxisServer(); } return myAxisServer; } // are we stopped? // latch to true if stop() is called private boolean stopped = false; /** * Accept requests from a given TCP port and send them through the * Axis engine for processing. */ public void run() { log.info(Messages.getMessage("start00", "SimpleAxisServer", new Integer(getServerSocket().getLocalPort()).toString())); // Accept and process requests from the socket while (!stopped) { Socket socket = null; try { socket = serverSocket.accept(); } catch (java.io.InterruptedIOException iie) { } catch (Exception e) { log.debug(Messages.getMessage("exception00"), e); break; } if (socket != null) { SimpleAxisWorker worker = new SimpleAxisWorker(this, socket); if (doThreads) { Thread thread = new Thread(worker); thread.setDaemon(true); thread.start(); } else { worker.run(); } } } log.info(Messages.getMessage("quit00", "SimpleAxisServer")); } // per thread socket information private ServerSocket serverSocket; /** * Obtain the serverSocket that that SimpleAxisServer is listening on. */ public ServerSocket getServerSocket() { return serverSocket; } /** * Set the serverSocket this server should listen on. * (note : changing this will not affect a running server, but if you * stop() and then start() the server, the new socket will be used). */ public void setServerSocket(ServerSocket serverSocket) { this.serverSocket = serverSocket; } /** * Start this server. * <p/> * Spawns a worker thread to listen for HTTP requests. * * @param daemon a boolean indicating if the thread should be a daemon. */ public void start(boolean daemon) throws Exception { if (doThreads) { Thread thread = new Thread(this); thread.setDaemon(daemon); thread.start(); } else { run(); } } /** * Start this server as a NON-daemon. */ public void start() throws Exception { start(false); } /** * Stop this server. * <p/> * This will interrupt any pending accept(). */ public void stop() throws Exception { /* * Close the server socket cleanly, but avoid fresh accepts while * the socket is closing. */ stopped = true; try { serverSocket.close(); } catch (Exception e) { log.info(Messages.getMessage("exception00"), e); } log.info(Messages.getMessage("quit00", "SimpleAxisServer")); // Kill the JVM, which will interrupt pending accepts even on linux. System.exit(0); } /** * Server process. */ public static void main(String args[]) { SimpleAxisServer sas = new SimpleAxisServer(); Options opts = null; try { opts = new Options(args); } catch (MalformedURLException e) { log.error(Messages.getMessage("malformedURLException00"), e); return; } try { doThreads = (opts.isFlagSet('t') > 0); int port = opts.getPort(); ServerSocket ss = null; // Try five times for (int i = 0; i < 5; i++) { try { ss = new ServerSocket(port); break; } catch (java.net.BindException be) { log.debug(Messages.getMessage("exception00"), be); if (i < 4) { // At 3 second intervals. Thread.sleep(3000); } else { throw new Exception(Messages.getMessage("unableToStartServer00", Integer.toString(port))); } } } sas.setServerSocket(ss); sas.start(); } catch (Exception e) { log.error(Messages.getMessage("exception00"), e); return; } } }
SimpleAxisServer.java |