package org.argeo.cms.jetty;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-import javax.websocket.DeploymentException;
-import javax.websocket.server.ServerContainer;
-import javax.websocket.server.ServerEndpointConfig;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.CmsState;
-import org.argeo.cms.CmsDeployProperty;
-import org.argeo.cms.websocket.javax.server.CmsWebSocketConfigurator;
-import org.argeo.cms.websocket.javax.server.TestEndpoint;
-import org.eclipse.jetty.http.UriCompliance;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.SecureRequestCustomizer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer;
-import org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer.Configurator;
-
-public class CmsJettyServer {
- private static final CmsLog log = CmsLog.getLog(CmsJettyServer.class);
-
- private static final int DEFAULT_IDLE_TIMEOUT = 30000;
+/** A {@link JettyHttpServer} which is compatible with Equinox servlets. */
+public class CmsJettyServer extends JettyHttpServer {
private static final String CONTEXT_TEMPDIR = "javax.servlet.context.tempdir";
-
// Equinox compatibility
private static final String INTERNAL_CONTEXT_CLASSLOADER = "org.eclipse.equinox.http.jetty.internal.ContextClassLoader";
-
- private Server server;
private Path tempDir;
- private ServerConnector httpConnector;
- private ServerConnector httpsConnector;
-
- // WebSocket
- private ServerContainer wsServerContainer;
- private ServerEndpointConfig.Configurator wsEndpointConfigurator;
-
- private CmsState cmsState;
-
- public void start() {
- try {
- tempDir = Files.createTempDirectory("jetty");
-
- server = new Server(new QueuedThreadPool(10, 1));
-
- configure();
- // context.addServlet(new ServletHolder(new RWTServlet()), "/" + entryPoint);
- // Required to serve rwt-resources. It is important that this is last.
-// ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
-// context.addServlet(holderPwd, "/");
-
- if (httpConnector != null) {
- httpConnector.open();
- server.addConnector(httpConnector);
- }
-
- if (httpsConnector != null) {
- httpsConnector.open();
- server.addConnector(httpsConnector);
- }
-
- // holder
-
- // context
- ServletContextHandler httpContext = createHttpContext();
- // httpContext.addServlet(holder, "/*");
- addServlets(httpContext);
- enableWebSocket(httpContext);
- server.setHandler(httpContext);
-
- //
- // START
- server.start();
- //
-
- Runtime.getRuntime().addShutdownHook(new Thread(() -> stop(), "Jetty shutdown"));
-
- log.info(httpPortsMsg());
- } catch (Exception e) {
- throw new IllegalStateException("Cannot start Jetty HTTPS server", e);
- }
- }
-
protected void addServlets(ServletContextHandler servletContextHandler) throws ServletException {
}
- public Integer getHttpPort() {
- if (httpConnector == null)
- return null;
- return httpConnector.getLocalPort();
- }
-
- public Integer getHttpsPort() {
- if (httpsConnector == null)
- return null;
- return httpsConnector.getLocalPort();
- }
-
- public void stop() {
+ @Override
+ public void start() {
try {
- // serverConnector.close();
- server.stop();
- // TODO delete temp dir
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-
- protected void configure() {
- HttpConfiguration http_config = new HttpConfiguration();
-
- String httpPortStr = getFrameworkProp(CmsDeployProperty.HTTP_PORT);
- String httpsPortStr = getFrameworkProp(CmsDeployProperty.HTTPS_PORT);
-
- /// TODO make it more generic
- String httpHost = getFrameworkProp(CmsDeployProperty.HOST);
-// String httpsHost = getFrameworkProp(
-// JettyConfig.JETTY_PROPERTY_PREFIX + CmsHttpConstants.HTTPS_HOST);
-
- // try {
- if (httpPortStr != null || httpsPortStr != null) {
- boolean httpEnabled = httpPortStr != null;
- // props.put(JettyHttpConstants.HTTP_ENABLED, httpEnabled);
- boolean httpsEnabled = httpsPortStr != null;
- // props.put(JettyHttpConstants.HTTPS_ENABLED, httpsEnabled);
- if (httpsEnabled) {
- int httpsPort = Integer.parseInt(httpsPortStr);
- http_config.setSecureScheme("https");
- http_config.setSecurePort(httpsPort);
- }
-
- if (httpEnabled) {
- int httpPort = Integer.parseInt(httpPortStr);
- httpConnector = new ServerConnector(server, new HttpConnectionFactory(http_config));
- httpConnector.setPort(httpPort);
- httpConnector.setHost(httpHost);
- httpConnector.setIdleTimeout(DEFAULT_IDLE_TIMEOUT);
- }
-
- if (httpsEnabled) {
-
- SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
- // sslContextFactory.setKeyStore(KeyS)
-
- sslContextFactory.setKeyStoreType(getFrameworkProp(CmsDeployProperty.SSL_KEYSTORETYPE));
- sslContextFactory.setKeyStorePath(getFrameworkProp(CmsDeployProperty.SSL_KEYSTORE));
- sslContextFactory.setKeyStorePassword(getFrameworkProp(CmsDeployProperty.SSL_PASSWORD));
- // sslContextFactory.setKeyManagerPassword(getFrameworkProp(CmsDeployProperty.SSL_KEYPASSWORD));
- sslContextFactory.setProtocol("TLS");
-
- sslContextFactory.setTrustStoreType(getFrameworkProp(CmsDeployProperty.SSL_TRUSTSTORETYPE));
- sslContextFactory.setTrustStorePath(getFrameworkProp(CmsDeployProperty.SSL_TRUSTSTORE));
- sslContextFactory.setTrustStorePassword(getFrameworkProp(CmsDeployProperty.SSL_TRUSTSTOREPASSWORD));
-
- String wantClientAuth = getFrameworkProp(CmsDeployProperty.SSL_WANTCLIENTAUTH);
- if (wantClientAuth != null && wantClientAuth.equals(Boolean.toString(true)))
- sslContextFactory.setWantClientAuth(true);
- String needClientAuth = getFrameworkProp(CmsDeployProperty.SSL_NEEDCLIENTAUTH);
- if (needClientAuth != null && needClientAuth.equals(Boolean.toString(true)))
- sslContextFactory.setNeedClientAuth(true);
-
- // HTTPS Configuration
- HttpConfiguration https_config = new HttpConfiguration(http_config);
- https_config.addCustomizer(new SecureRequestCustomizer());
- https_config.setUriCompliance(UriCompliance.LEGACY);
-
- // HTTPS connector
- httpsConnector = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, "http/1.1"),
- new HttpConnectionFactory(https_config));
- int httpsPort = Integer.parseInt(httpsPortStr);
- httpsConnector.setPort(httpsPort);
- httpsConnector.setHost(httpHost);
- }
-
- }
-
- }
-
- protected void enableWebSocket(ServletContextHandler servletContextHandler) {
- String webSocketEnabled = getFrameworkProp(CmsDeployProperty.WEBSOCKET_ENABLED);
- // web socket
- if (webSocketEnabled != null && webSocketEnabled.equals(Boolean.toString(true))) {
- JavaxWebSocketServletContainerInitializer.configure(servletContextHandler, new Configurator() {
-
- @Override
- public void accept(ServletContext servletContext, ServerContainer serverContainer)
- throws DeploymentException {
- wsServerContainer = serverContainer;
-
- wsEndpointConfigurator = new CmsWebSocketConfigurator();
-
- ServerEndpointConfig config = ServerEndpointConfig.Builder
- .create(TestEndpoint.class, "/ws/test/events/").configurator(wsEndpointConfigurator)
- .build();
- try {
- wsServerContainer.addEndpoint(config);
- } catch (DeploymentException e) {
- throw new IllegalStateException("Cannot initalise the WebSocket server runtime.", e);
- }
- }
- });
+ tempDir = Files.createTempDirectory("jetty");
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot create temp dir", e);
}
+ super.start();
}
- protected ServletContextHandler createHttpContext() {
- ServletContextHandler httpContext = new ServletContextHandler();
- httpContext.setAttribute(INTERNAL_CONTEXT_CLASSLOADER, Thread.currentThread().getContextClassLoader());
- httpContext.setClassLoader(this.getClass().getClassLoader());
- httpContext.setContextPath("/");
+ protected ServletContextHandler createRootContextHandler() {
+ ServletContextHandler servletContextHandler = new ServletContextHandler();
+ servletContextHandler.setAttribute(INTERNAL_CONTEXT_CLASSLOADER,
+ Thread.currentThread().getContextClassLoader());
+ servletContextHandler.setClassLoader(this.getClass().getClassLoader());
+ servletContextHandler.setContextPath("/");
- httpContext.setAttribute(CONTEXT_TEMPDIR, tempDir.toAbsolutePath().toFile());
+ servletContextHandler.setAttribute(CONTEXT_TEMPDIR, tempDir.toAbsolutePath().toFile());
SessionHandler handler = new SessionHandler();
handler.setMaxInactiveInterval(-1);
- httpContext.setSessionHandler(handler);
-
- return httpContext;
- }
-
- private String httpPortsMsg() {
+ servletContextHandler.setSessionHandler(handler);
- return (httpConnector != null ? "HTTP " + getHttpPort() + " " : " ")
- + (httpsConnector != null ? "HTTPS " + getHttpsPort() : "");
+ return servletContextHandler;
}
- private String getFrameworkProp(CmsDeployProperty deployProperty) {
- return cmsState.getDeployProperty(deployProperty.getProperty());
+ @Override
+ protected void configureRootContextHandler(ServletContextHandler servletContextHandler) throws ServletException {
+ addServlets(servletContextHandler);
}
-
- public void setCmsState(CmsState cmsState) {
- this.cmsState = cmsState;
- }
-
}