Package org.openrdf.http.server

Source Code of org.openrdf.http.server.SesameServer$StopRestlet

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2007-2010.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.http.server;

import static org.restlet.data.Status.CLIENT_ERROR_FORBIDDEN;
import static org.restlet.data.Status.SUCCESS_ACCEPTED;

import java.io.File;

import org.restlet.Component;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.Server;
import org.restlet.data.Form;
import org.restlet.data.Parameter;
import org.restlet.data.Protocol;
import org.restlet.data.Status;
import org.restlet.util.Series;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.openrdf.repository.manager.RepositoryManager;

/**
* A Sesame server that can be started and stopped programmatically.
*/
public class SesameServer {

  /**
   * The default server port (<tt>8080</tt>).
   */
  public static final int DEFAULT_PORT = 8080;

  public static final String SHUTDOWN_PATH = "stop";

  public static final String SHUTDOWN_KEY_PARAM = "key";

  private final Logger logger = LoggerFactory.getLogger(this.getClass());

  private final File dataDir;

  private final int port;

  private final int sslPort;

  private Component component;

  private SesameApplication sesameApplication;

  private String shutDownKey;

  /**
   * Creates a new Sesame server that will listen to {@link #DEFAULT_PORT the
   * default port}.
   *
   * @param dataDir
   *        The directory containing the server's configuration data,
   *        repository data, etc.
   */
  public SesameServer(File dataDir) {
    this(dataDir, DEFAULT_PORT, -1);
  }

  /**
   * Creates a new Sesame server.
   *
   * @param dataDir
   *        The directory containing the server's configuration data,
   *        repository data, etc.
   * @param port
   *        The server port.
   */
  public SesameServer(File dataDir, int port) {
    this(dataDir, port, -1);
  }

  /**
   * Creates a new Sesame server.
   *
   * @param dataDir
   *        The directory containing the server's configuration data,
   *        repository data, etc.
   * @param port
   *        The server port.
   */
  public SesameServer(File dataDir, int port, int sslPort) {
    this.dataDir = dataDir;
    this.port = port;
    this.sslPort = sslPort;
  }

  /**
   * Gets the server's data directory.
   */
  public File getDataDir() {
    return dataDir;
  }

  /**
   * Gets the server's port number.
   */
  public int getPort() {
    return port;
  }
 
  public int getSslPort() {
    return sslPort;
  }

  public synchronized void setShutdownKey(String shutdownKey) {
    if (shutdownKey == null) {
      throw new IllegalArgumentException("shutdownKey must not be null");
    }

    this.shutDownKey = shutdownKey;
  }

  public synchronized String getShutdownKey() {
    return shutDownKey;
  }

  public RepositoryManager getRepositoryManager() {
    return sesameApplication.getRepositoryManager();
  }

  /**
   * Starts the server.
   */
  public synchronized void start()
    throws Exception
  {
    component = new Component();
    component.getServers().add(Protocol.HTTP, port);
    if (sslPort > 0) {
      Server httpsServer = component.getServers().add(Protocol.HTTPS, sslPort);
      Series<Parameter> httpsParameters = httpsServer.getContext().getParameters();
      copySystemProperty("javax.net.ssl.keyStore", httpsParameters, "keystorePath");
      copySystemProperty("javax.net.ssl.keyStorePassword", httpsParameters, "keystorePassword");
      copySystemProperty("javax.net.ssl.keyStoreType", httpsParameters, "keystoreType");
//      httpsParameters.add("keyPassword", "changeit");
    }
    component.getClients().add(Protocol.HTTP);
    component.getClients().add(Protocol.HTTPS);
    component.getLogService().setEnabled(false);

    Context appContext = component.getContext().createChildContext();
    sesameApplication = new SesameApplication(appContext, dataDir);

    component.getDefaultHost().attachDefault(sesameApplication);

    if (getShutdownKey() != null) {
      component.getDefaultHost().attach("/" + SHUTDOWN_PATH, new StopRestlet());
    }

    try {
      component.start();
    }
    catch (Exception e) {
      e.printStackTrace();
      stop();
      throw e;
    }
  }

  private final void copySystemProperty(String systemProp, Series<Parameter> parameters, String param) {
    String systemPropValue = System.getProperty(systemProp);
    if (systemPropValue != null) {
      parameters.set(param, systemPropValue);
    }
  }

  /**
   * Stops the server.
   */
  public synchronized void stop()
    throws Exception
  {
    if (component != null) {
      component.stop();
    }
  }

  private void scheduleShutdown() {
    Thread t = new Thread("Server shutdown thread") {

      @Override
      public void run() {
        // give the server some time to reply to the shutdown request
        // FIXME: better to let the server shut down gracefully
        try {
          sleep(100L);
        }
        catch (InterruptedException ignore) {
        }

        try {
          SesameServer.this.stop();
        }
        catch (Exception e) {
          logger.error("Failed to stop server", e);
        }
      }
    };
    t.start();
  }

  public class StopRestlet extends Restlet {

    @Override
    public void handle(Request request, Response response) {
      if (request.getMethod().getName().equalsIgnoreCase("POST")) {
        handlePost(request, response);
      }
      else {
        response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
      }
    }

    private void handlePost(Request request, Response response) {
      Form params = new Form(request.getEntity());
      String key = params.getFirstValue(SHUTDOWN_KEY_PARAM);
      if (key != null && key.equals(getShutdownKey())) {
        response.setStatus(SUCCESS_ACCEPTED);
        logger.info("Server shutting down");
        scheduleShutdown();
      }
      else {
        response.setStatus(CLIENT_ERROR_FORBIDDEN, "invalid shutdown key");
      }
    }
  }
}
TOP

Related Classes of org.openrdf.http.server.SesameServer$StopRestlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.