/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package de.cismet.cids.server.ws.rest;
import Sirius.server.ServerExitError;
import Sirius.server.property.ServerProperties;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import org.apache.log4j.Logger;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import java.util.HashMap;
import java.util.Map;
/**
* DOCUMENT ME!
*
* @author martin.scholl@cismet.de
* @version $Revision$, $Date$
*/
public final class RESTfulService {
//~ Static fields/initializers ---------------------------------------------
private static final transient Logger LOG = Logger.getLogger(RESTfulService.class);
private static RESTfulService instance;
private static final int HEADER_BUFFER_SIZE = 512 * 1024; // = 512kb
//~ Instance fields --------------------------------------------------------
private final transient int port;
private final transient Server server;
//~ Constructors -----------------------------------------------------------
/**
* Creates a new RESTfulService object.
*
* @param properties port DOCUMENT ME!
*
* @throws ServerExitError DOCUMENT ME!
*/
private RESTfulService(final ServerProperties properties) throws ServerExitError {
final Map<String, String> initParams = new HashMap<String, String>();
initParams.put("com.sun.jersey.config.property.packages", "de.cismet.cids.server.ws.rest"); // NOI18N
final ServletHolder servlet = new ServletHolder(ServletContainer.class);
servlet.setInitParameters(initParams);
this.port = properties.getRestPort();
server = new Server();
server.addConnector(getConnector(properties));
final Context context = new Context(server, "/", Context.SESSIONS); // NOI18N
context.addServlet(servlet, "/*"); // NOI18N
try {
server.start();
} catch (final Exception ex) {
final String message = "could not create jetty web container on port: " + port; // NOI18N
LOG.error(message, ex);
throw new ServerExitError(message, ex);
}
}
//~ Methods ----------------------------------------------------------------
/**
* DOCUMENT ME!
*
* @param properties DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws ServerExitError DOCUMENT ME!
*/
private Connector getConnector(final ServerProperties properties) throws ServerExitError {
final Connector connector;
if (properties.isRestDebug()) {
LOG.warn("server REST interface is in debug mode, no security applied!"); // NOI18N
connector = new SocketConnector();
} else {
if (LOG.isInfoEnabled()) {
LOG.info("server REST interface uses SSL connector"); // NOI18N
}
try {
final SslSocketConnector ssl = new SslSocketConnector();
ssl.setMaxIdleTime(30000);
ssl.setKeystore(properties.getRestServerKeystore());
ssl.setPassword(properties.getRestServerKeystorePW());
ssl.setKeyPassword(properties.getRestServerKeystoreKeyPW());
final boolean clientAuth = properties.isRestClientAuth();
if (clientAuth) {
ssl.setTruststore(properties.getRestClientKeystore());
ssl.setTrustPassword(properties.getRestClientKeystorePW());
}
ssl.setWantClientAuth(clientAuth);
ssl.setNeedClientAuth(clientAuth);
connector = ssl;
} catch (final Exception e) {
final String message = "cannot initialise SSL connector"; // NOI18N
LOG.error(message, e);
throw new ServerExitError(message, e);
}
}
connector.setPort(port);
connector.setHeaderBufferSize(HEADER_BUFFER_SIZE);
return connector;
}
/**
* DOCUMENT ME!
*
* @param properties port DOCUMENT ME!
*
* @throws ServerExitError DOCUMENT ME!
*/
public static synchronized void up(final ServerProperties properties) throws ServerExitError {
if (!isUp()) {
instance = new RESTfulService(properties);
if (LOG.isInfoEnabled()) {
LOG.info("RESTfulService started @ port: " + properties.getRestPort()); // NOI18N
}
}
}
/**
* DOCUMENT ME!
*/
public static synchronized void down() {
if (isUp()) {
try {
instance.server.stop();
// instance.selector.stopEndpoint();
if (LOG.isInfoEnabled()) {
LOG.info("RESTfulService stopped @ port: " + getPort()); // NOI18N
}
} catch (final Exception ex) {
// LOG.warn("could not stop jetty", ex);
LOG.warn("could not stop grizzly", ex); // NOI18N
}
instance = null;
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static synchronized boolean isUp() {
return instance != null;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public static synchronized int getPort() {
if (isUp()) {
return instance.port;
} else {
return -1;
}
}
}