- Single Jetty instnace (fixes #19)

This commit is contained in:
Sebastian Stenzel
2015-01-15 12:27:10 +01:00
parent f0fa4fcf3d
commit 0aef60efc4
11 changed files with 143 additions and 62 deletions
@@ -8,6 +8,10 @@
******************************************************************************/
package org.cryptomator.webdav;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -18,6 +22,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.slf4j.Logger;
@@ -31,40 +36,33 @@ public final class WebDavServer {
private static final int MAX_THREADS = 200;
private static final int MIN_THREADS = 4;
private static final int THREAD_IDLE_SECONDS = 20;
private static final WebDavServer INSTANCE = new WebDavServer();
private final Server server;
private int port;
private final ServerConnector localConnector;
private final ServletContextHandler servletContext;
public WebDavServer() {
public static WebDavServer getInstance() {
return INSTANCE;
}
private WebDavServer() {
final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(MAX_PENDING_REQUESTS);
final ThreadPool tp = new QueuedThreadPool(MAX_THREADS, MIN_THREADS, THREAD_IDLE_SECONDS, queue);
server = new Server(tp);
localConnector = new ServerConnector(server);
localConnector.setHost(LOCALHOST);
servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContext.setContextPath("/");
server.setConnectors(new Connector[] {localConnector});
server.setHandler(servletContext);
}
/**
* @param workDir Path of encrypted folder.
* @param cryptor A fully initialized cryptor instance ready to en- or decrypt streams.
* @return <code>true</code> upon success
*/
public synchronized boolean start(final String workDir, final boolean checkFileIntegrity, final Cryptor cryptor) {
final ServerConnector connector = new ServerConnector(server);
connector.setHost(LOCALHOST);
final String contextPath = "/";
final String servletPathSpec = "/*";
final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.addServlet(getWebDavServletHolder(workDir, contextPath, checkFileIntegrity, cryptor), servletPathSpec);
context.setContextPath(contextPath);
server.setHandler(context);
public synchronized void start() {
try {
server.setConnectors(new Connector[] {connector});
server.start();
port = connector.getLocalPort();
return true;
LOG.info("Cryptomator is running on port {}", getPort());
} catch (Exception ex) {
LOG.error("Server couldn't be started", ex);
return false;
throw new RuntimeException("Server couldn't be started", ex);
}
}
@@ -72,14 +70,33 @@ public final class WebDavServer {
return server.isRunning();
}
public synchronized boolean stop() {
public synchronized void stop() {
try {
server.stop();
port = 0;
} catch (Exception ex) {
LOG.error("Server couldn't be stopped", ex);
}
return server.isStopped();
}
/**
* @param workDir Path of encrypted folder.
* @param cryptor A fully initialized cryptor instance ready to en- or decrypt streams.
* @return servlet
*/
public ServletLifeCycleAdapter createServlet(final Path workDir, final boolean checkFileIntegrity, final Cryptor cryptor) {
try {
final URI uri = new URI(null, null, localConnector.getHost(), localConnector.getLocalPort(), "/" + UUID.randomUUID().toString(), null, null);
final String pathPrefix = uri.getRawPath() + "/";
final String pathSpec = pathPrefix + "*";
final ServletHolder servlet = getWebDavServletHolder(workDir.toString(), pathPrefix, checkFileIntegrity, cryptor);
servletContext.addServlet(servlet, pathSpec);
LOG.info("{} available on http://{}", workDir, uri.getRawSchemeSpecificPart());
return new ServletLifeCycleAdapter(servlet, uri);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Can't create URI from given workDir", e);
}
}
private ServletHolder getWebDavServletHolder(final String workDir, final String contextPath, final boolean checkFileIntegrity, final Cryptor cryptor) {
@@ -91,7 +108,50 @@ public final class WebDavServer {
}
public int getPort() {
return port;
return localConnector.getLocalPort();
}
/**
* Exposes implementation-specific methods to other modules.
*/
public class ServletLifeCycleAdapter {
private final LifeCycle lifecycle;
private final URI servletUri;
private ServletLifeCycleAdapter(LifeCycle lifecycle, URI servletUri) {
this.lifecycle = lifecycle;
this.servletUri = servletUri;
}
public boolean isRunning() {
return lifecycle.isRunning();
}
public boolean start() {
try {
lifecycle.start();
return true;
} catch (Exception e) {
LOG.error("Failed to start", e);
return false;
}
}
public boolean stop() {
try {
lifecycle.stop();
return true;
} catch (Exception e) {
LOG.error("Failed to stop", e);
return false;
}
}
public URI getServletUri() {
return servletUri;
}
}
}