| 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 |