<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" activate="start" deactivate="stop" name="Jetty Service Factory">
- <implementation class="org.argeo.cms.servlet.internal.jetty.JettyConfig"/>
+ <implementation class="org.argeo.cms.equinox.http.jetty.EquinoxJettyServer"/>
<property name="service.pid" type="String" value="org.argeo.equinox.jetty.config"/>
<reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
</scr:component>
-Fragment-Host: org.eclipse.equinox.http.jetty
-
Service-Component: \
OSGI-INF/jettyServiceFactory.xml,\
--- /dev/null
+package org.argeo.cms.equinox.http.jetty;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionIdListener;
+import javax.servlet.http.HttpSessionListener;
+
+import org.argeo.cms.jetty.CmsJettyServer;
+import org.eclipse.equinox.http.servlet.HttpServiceServlet;
+import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.osgi.framework.Constants;
+
+public class EquinoxJettyServer extends CmsJettyServer {
+ private static final String INTERNAL_CONTEXT_CLASSLOADER = "org.eclipse.equinox.http.jetty.internal.ContextClassLoader";
+
+ @Override
+ protected void addServlets(ServletContextHandler servletContextHandler) throws ServletException {
+ ServletHolder holder = new ServletHolder(new InternalHttpServiceServlet());
+ holder.setInitOrder(0);
+ holder.setInitParameter(Constants.SERVICE_VENDOR, "Eclipse.org"); //$NON-NLS-1$
+ holder.setInitParameter(Constants.SERVICE_DESCRIPTION, "Equinox Jetty-based Http Service"); //$NON-NLS-1$
+
+ // holder.setInitParameter(JettyConstants.CONTEXT_PATH,
+ // httpContext.getContextPath());
+ servletContextHandler.addServlet(holder, "/*");
+
+ // post-start
+ SessionHandler sessionManager = servletContextHandler.getSessionHandler();
+ sessionManager.addEventListener((HttpSessionIdListener) holder.getServlet());
+ }
+
+ public static class InternalHttpServiceServlet implements HttpSessionListener, HttpSessionIdListener, Servlet {
+ private final Servlet httpServiceServlet = new HttpServiceServlet();
+ private ClassLoader contextLoader;
+ private final Method sessionDestroyed;
+ private final Method sessionIdChanged;
+
+ public InternalHttpServiceServlet() {
+ Class<?> clazz = httpServiceServlet.getClass();
+
+ try {
+ sessionDestroyed = clazz.getMethod("sessionDestroyed", new Class<?>[] { String.class }); //$NON-NLS-1$
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ try {
+ sessionIdChanged = clazz.getMethod("sessionIdChanged", new Class<?>[] { String.class }); //$NON-NLS-1$
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ ServletContext context = config.getServletContext();
+ contextLoader = (ClassLoader) context.getAttribute(INTERNAL_CONTEXT_CLASSLOADER);
+
+ Thread thread = Thread.currentThread();
+ ClassLoader current = thread.getContextClassLoader();
+ thread.setContextClassLoader(contextLoader);
+ try {
+ httpServiceServlet.init(config);
+ } finally {
+ thread.setContextClassLoader(current);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ Thread thread = Thread.currentThread();
+ ClassLoader current = thread.getContextClassLoader();
+ thread.setContextClassLoader(contextLoader);
+ try {
+ httpServiceServlet.destroy();
+ } finally {
+ thread.setContextClassLoader(current);
+ }
+ contextLoader = null;
+ }
+
+ @Override
+ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
+ Thread thread = Thread.currentThread();
+ ClassLoader current = thread.getContextClassLoader();
+ thread.setContextClassLoader(contextLoader);
+ try {
+ httpServiceServlet.service(req, res);
+ } finally {
+ thread.setContextClassLoader(current);
+ }
+ }
+
+ @Override
+ public ServletConfig getServletConfig() {
+ return httpServiceServlet.getServletConfig();
+ }
+
+ @Override
+ public String getServletInfo() {
+ return httpServiceServlet.getServletInfo();
+ }
+
+ @Override
+ public void sessionCreated(HttpSessionEvent event) {
+ // Nothing to do.
+ }
+
+ @Override
+ public void sessionDestroyed(HttpSessionEvent event) {
+ Thread thread = Thread.currentThread();
+ ClassLoader current = thread.getContextClassLoader();
+ thread.setContextClassLoader(contextLoader);
+ try {
+ sessionDestroyed.invoke(httpServiceServlet, event.getSession().getId());
+ } catch (IllegalAccessException | IllegalArgumentException e) {
+ // not likely
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e.getCause());
+ } finally {
+ thread.setContextClassLoader(current);
+ }
+ }
+
+ @Override
+ public void sessionIdChanged(HttpSessionEvent event, String oldSessionId) {
+ Thread thread = Thread.currentThread();
+ ClassLoader current = thread.getContextClassLoader();
+ thread.setContextClassLoader(contextLoader);
+ try {
+ sessionIdChanged.invoke(httpServiceServlet, oldSessionId);
+ } catch (IllegalAccessException | IllegalArgumentException e) {
+ // not likely
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e.getCause());
+ } finally {
+ thread.setContextClassLoader(current);
+ }
+ }
+ }
+
+}
package org.argeo.cms.servlet.internal.jetty;
+import java.io.File;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
import org.argeo.util.LangUtils;
import org.eclipse.equinox.http.jetty.JettyConfigurator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
// We need to start asynchronously so that Jetty bundle get started by lazy init
// due to the non-configurable behaviour of its activator
ForkJoinPool.commonPool().execute(() -> {
- Dictionary<String, ?> properties = getHttpServerConfig();
+ Dictionary<String, Object> properties = getHttpServerConfig();
startServer(properties);
});
}
- public void startServer(Dictionary<String, ?> properties) {
+ public void startServer(Dictionary<String, Object> properties) {
// Explicitly configures Jetty so that the default server is not started by the
// activator of the Equinox Jetty bundle.
Map<String, String> config = LangUtils.dictToStringMap(properties);
}
}
- long begin = System.currentTimeMillis();
- int tryCount = 60;
- try {
- while (tryCount > 0) {
- try {
- // FIXME deal with multiple ids
- JettyConfigurator.startServer(CmsConstants.DEFAULT, new Hashtable<>(config));
-
- Object httpPort = config.get(JettyHttpConstants.HTTP_PORT);
- Object httpsPort = config.get(JettyHttpConstants.HTTPS_PORT);
- log.info(httpPortsMsg(httpPort, httpsPort));
-
- // Explicitly starts Jetty OSGi HTTP bundle, so that it gets triggered if OSGi
- // configuration is not cleaned
- FrameworkUtil.getBundle(JettyConfigurator.class).start();
- return;
- } catch (IllegalStateException e) {
- // e.printStackTrace();
- // Jetty may not be ready
- try {
- Thread.sleep(1000);
- } catch (Exception e1) {
- // silent
- }
- tryCount--;
- }
- }
- long duration = System.currentTimeMillis() - begin;
- log.error("Gave up with starting Jetty server after " + (duration / 1000) + " s");
- } catch (Exception e) {
- log.error("Cannot start default Jetty server with config " + properties, e);
- }
+ properties.put(Constants.SERVICE_PID, "default");
+ File jettyWorkDir = new File(bc.getDataFile(""), "jettywork"); //$NON-NLS-1$
+ jettyWorkDir.mkdir();
+
+// HttpServerManager serverManager = new HttpServerManager(jettyWorkDir);
+// try {
+// serverManager.updated("default", properties);
+// } catch (ConfigurationException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+ Object httpPort = config.get(JettyHttpConstants.HTTP_PORT);
+ Object httpsPort = config.get(JettyHttpConstants.HTTPS_PORT);
+ log.info(httpPortsMsg(httpPort, httpsPort));
+
+// long begin = System.currentTimeMillis();
+// int tryCount = 60;
+// try {
+// while (tryCount > 0) {
+// try {
+// // FIXME deal with multiple ids
+// JettyConfigurator.startServer(CmsConstants.DEFAULT, new Hashtable<>(config));
+//
+// Object httpPort = config.get(JettyHttpConstants.HTTP_PORT);
+// Object httpsPort = config.get(JettyHttpConstants.HTTPS_PORT);
+// log.info(httpPortsMsg(httpPort, httpsPort));
+//
+// // Explicitly starts Jetty OSGi HTTP bundle, so that it gets triggered if OSGi
+// // configuration is not cleaned
+// FrameworkUtil.getBundle(JettyConfigurator.class).start();
+// return;
+// } catch (IllegalStateException e) {
+// // e.printStackTrace();
+// // Jetty may not be ready
+// try {
+// Thread.sleep(1000);
+// } catch (Exception e1) {
+// // silent
+// }
+// tryCount--;
+// }
+// }
+// long duration = System.currentTimeMillis() - begin;
+// log.error("Gave up with starting Jetty server after " + (duration / 1000) + " s");
+// } catch (Exception e) {
+// log.error("Cannot start default Jetty server with config " + properties, e);
+// }
}
+++ /dev/null
-package org.argeo.cms.servlet.internal.jetty;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Map;
-
-import javax.websocket.DeploymentException;
-import javax.websocket.server.ServerContainer;
-import javax.websocket.server.ServerEndpointConfig;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.websocket.javax.server.CmsWebSocketConfigurator;
-import org.argeo.cms.websocket.javax.server.TestEndpoint;
-import org.argeo.util.LangUtils;
-import org.eclipse.equinox.http.jetty.JettyConfigurator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.osgi.util.tracker.ServiceTracker;
-
-@Deprecated
-public class JettyServiceFactory implements ManagedServiceFactory {
- private final static CmsLog log = CmsLog.getLog(JettyServiceFactory.class);
-
- final static String CMS_JETTY_CUSTOMIZER_CLASS = "org.argeo.equinox.jetty.CmsJettyCustomizer";
- // Argeo specific
- final static String WEBSOCKET_ENABLED = "websocket.enabled";
-
- private final BundleContext bc = FrameworkUtil.getBundle(JettyServiceFactory.class).getBundleContext();
-
- public void start() {
- ServiceTracker<ServerContainer, ServerContainer> serverSt = new ServiceTracker<ServerContainer, ServerContainer>(
- bc, ServerContainer.class, null) {
-
- @Override
- public ServerContainer addingService(ServiceReference<ServerContainer> reference) {
- ServerContainer serverContainer = super.addingService(reference);
-
- BundleContext bc = reference.getBundle().getBundleContext();
- ServiceReference<ServerEndpointConfig.Configurator> srConfigurator = bc
- .getServiceReference(ServerEndpointConfig.Configurator.class);
- ServerEndpointConfig.Configurator endpointConfigurator = bc.getService(srConfigurator);
- ServerEndpointConfig config = ServerEndpointConfig.Builder
- .create(TestEndpoint.class, "/ws/test/events/").configurator(endpointConfigurator).build();
- try {
- serverContainer.addEndpoint(config);
- } catch (DeploymentException e) {
- throw new IllegalStateException("Cannot initalise the WebSocket server runtime.", e);
- }
- return serverContainer;
- }
-
- };
- serverSt.open();
- }
-
- @Override
- public String getName() {
- return "Jetty Service Factory";
- }
-
- @Override
- public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
- // Explicitly configures Jetty so that the default server is not started by the
- // activator of the Equinox Jetty bundle.
- Map<String, String> config = LangUtils.dictToStringMap(properties);
- if (!config.isEmpty()) {
- config.put("customizer.class", CMS_JETTY_CUSTOMIZER_CLASS);
-
- // TODO centralise with Jetty extender
- Object webSocketEnabled = config.get(WEBSOCKET_ENABLED);
- if (webSocketEnabled != null && webSocketEnabled.toString().equals("true")) {
- bc.registerService(ServerEndpointConfig.Configurator.class, new CmsWebSocketConfigurator(), null);
- config.put(WEBSOCKET_ENABLED, "true");
- }
- }
-
- int tryCount = 60;
- try {
- tryGettyJetty: while (tryCount > 0) {
- try {
- // FIXME deal with multiple ids
- JettyConfigurator.startServer(CmsConstants.DEFAULT, new Hashtable<>(config));
- // Explicitly starts Jetty OSGi HTTP bundle, so that it gets triggered if OSGi
- // configuration is not cleaned
- FrameworkUtil.getBundle(JettyConfigurator.class).start();
- break tryGettyJetty;
- } catch (IllegalStateException e) {
- // Jetty may not be ready
- try {
- Thread.sleep(1000);
- } catch (Exception e1) {
- // silent
- }
- tryCount--;
- }
- }
- } catch (Exception e) {
- log.error("Cannot start default Jetty server with config " + properties, e);
- }
-
- }
-
- @Override
- public void deleted(String pid) {
- }
-
- public void stop() {
- try {
- JettyConfigurator.stopServer(CmsConstants.DEFAULT);
- } catch (Exception e) {
- log.error("Cannot stop default Jetty server.", e);
- }
-
- }
-
-}
if (httpsConnector != null)
for (ConnectionFactory connectionFactory : httpsConnector.getConnectionFactories()) {
if (connectionFactory instanceof SslConnectionFactory) {
- SslContextFactory.Server sslConnectionFactory = ((SslConnectionFactory) connectionFactory)
+ SslContextFactory.Server sslContextFactory = ((SslConnectionFactory) connectionFactory)
.getSslContextFactory();
- sslConnectionFactory.setTrustStorePath((String) settings.get(SSL_TRUSTSTORE));
- sslConnectionFactory.setTrustStoreType((String) settings.get(SSL_TRUSTSTORETYPE));
- sslConnectionFactory.setTrustStorePassword((String) settings.get(SSL_TRUSTSTOREPASSWORD));
+ sslContextFactory.setTrustStorePath((String) settings.get(SSL_TRUSTSTORE));
+ sslContextFactory.setTrustStoreType((String) settings.get(SSL_TRUSTSTORETYPE));
+ sslContextFactory.setTrustStorePassword((String) settings.get(SSL_TRUSTSTOREPASSWORD));
}
}
return super.customizeHttpsConnector(connector, settings);
+++ /dev/null
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
-org.eclipse.jdt.core.compiler.compliance=17
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
-org.eclipse.jdt.core.compiler.release=enabled
-org.eclipse.jdt.core.compiler.source=17
+++ /dev/null
-eclipse.preferences.version=1
-pluginProject.equinox=false
-pluginProject.extensions=false
-resolve.requirebundle=false
Import-Package: \
javax.servlet.http,\
-org.eclipse.jetty.util.component;version="[9.4,12)";resolution:=optional,\
-org.eclipse.jetty.http;version="[9.4,12)";resolution:=optional,\
-org.eclipse.jetty.io;version="[9.4,12)";resolution:=optional,\
-org.eclipse.jetty.security;version="[9.4,12)";resolution:=optional,\
-org.eclipse.jetty.server.handler;version="[9.4,12)";resolution:=optional,\
-org.eclipse.jetty.*;version="[9.4,12)";resolution:=optional,\
+org.eclipse.jetty.server.handler,\
+org.eclipse.jetty.util.component,\
*
\ No newline at end of file
--- /dev/null
+package org.argeo.cms.jetty;
+
+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;
+ 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() {
+ 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);
+ }
+ }
+ });
+ }
+ }
+
+ protected ServletContextHandler createHttpContext() {
+ ServletContextHandler httpContext = new ServletContextHandler();
+ httpContext.setAttribute(INTERNAL_CONTEXT_CLASSLOADER, Thread.currentThread().getContextClassLoader());
+ httpContext.setClassLoader(this.getClass().getClassLoader());
+ httpContext.setContextPath("/");
+
+ httpContext.setAttribute(CONTEXT_TEMPDIR, tempDir.toAbsolutePath().toFile());
+ SessionHandler handler = new SessionHandler();
+ handler.setMaxInactiveInterval(-1);
+ httpContext.setSessionHandler(handler);
+
+ return httpContext;
+ }
+
+ private String httpPortsMsg() {
+
+ return (httpConnector != null ? "HTTP " + getHttpPort() + " " : " ")
+ + (httpsConnector != null ? "HTTPS " + getHttpsPort() : "");
+ }
+
+ private String getFrameworkProp(CmsDeployProperty deployProperty) {
+ return cmsState.getDeployProperty(deployProperty.getProperty());
+ }
+
+ public void setCmsState(CmsState cmsState) {
+ this.cmsState = cmsState;
+ }
+
+}
+++ /dev/null
-package org.argeo.cms.lib.jetty;
-
-import java.nio.file.Path;
-
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.servlet.DefaultServlet;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-
-public class CmsJettyServer {
- private Server server;
- private ServerConnector serverConnector;
- private Path tempDir;
-
- public void start() {
- server = new Server(new QueuedThreadPool(10, 1));
- serverConnector = new ServerConnector(server);
- serverConnector.setPort(0);
- server.setConnectors(new Connector[] { serverConnector });
-
- ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
- context.setContextPath("/");
- server.setHandler(context);
-
- //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, "/");
-
- try {
- server.start();
- } catch (Exception e) {
- throw new IllegalStateException("Cannot start Jetty server", e);
- }
- Runtime.getRuntime().addShutdownHook(new Thread(() -> stop(), "Jetty shutdown"));
- }
-
- public void stop() {
- try {
- serverConnector.close();
- server.stop();
- // TODO delete temp dir
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
-}
import org.argeo.api.cli.DescribedCommand;
import org.argeo.api.cms.CmsApp;
import org.argeo.api.cms.CmsContext;
+import org.argeo.api.cms.CmsState;
+import org.argeo.cms.jetty.CmsJettyServer;
import org.argeo.cms.runtime.StaticCms;
import org.argeo.cms.swt.app.CmsUserApp;
import org.argeo.cms.web.CmsWebApp;
Path instancePath = Paths.get(dataPath);
System.setProperty("osgi.instance.area", instancePath.toUri().toString());
+ System.setProperty("argeo.http.port", "0");
StaticCms staticCms = new StaticCms() {
@Override
CmsWebApp cmsWebApp = new CmsWebApp();
Component<CmsWebApp> cmsWebAppC = new Component.Builder<>(cmsWebApp) //
.addType(ApplicationConfiguration.class) //
+ .addType(CmsWebApp.class) //
.addDependency(cmsAppC.getType(CmsApp.class), cmsWebApp::setCmsApp, null) //
.build(register);
- RwtRunner rwtRunner = new RwtRunner();
- Component<RwtRunner> rwtRunnerC = new Component.Builder<>(rwtRunner) //
- .addActivation(rwtRunner::init) //
- .addDeactivation(rwtRunner::destroy) //
- .addType(RwtRunner.class) //
- .addDependency(cmsWebAppC.getType(ApplicationConfiguration.class),
- rwtRunner::setApplicationConfiguration, null) //
+ RapJettyServer rwtRunner = new RapJettyServer();
+ Component<RapJettyServer> rwtRunnerC = new Component.Builder<>(rwtRunner) //
+ .addActivation(rwtRunner::start) //
+ .addDeactivation(rwtRunner::stop) //
+ .addType(CmsJettyServer.class) //
+ .addDependency(register.getSingleton(CmsState.class), rwtRunner::setCmsState, null) //
+ .addDependency(cmsWebAppC.getType(CmsWebApp.class), rwtRunner::setCmsWebApp, null) //
.build(register);
}
}
try {
// open browser in app mode
Thread.sleep(2000);// wait for RWT to be ready
- Runtime.getRuntime().exec("google-chrome --app=http://localhost:"
- + staticCms.getComponentRegister().getObject(RwtRunner.class).getEffectivePort() + "/data");
+ String browserCommand = "google-chrome --app=http://localhost:"
+ + staticCms.getComponentRegister().getObject(CmsJettyServer.class).getHttpPort() + "/data";
+ Runtime.getRuntime().exec(browserCommand);
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
--- /dev/null
+package org.argeo.cms.swt.rap.cli;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+
+import org.argeo.cms.jetty.CmsJettyServer;
+import org.argeo.cms.web.CmsWebApp;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.rap.rwt.application.ApplicationRunner;
+import org.eclipse.rap.rwt.engine.RWTServlet;
+
+public class RapJettyServer extends CmsJettyServer {
+ private CmsWebApp cmsWebApp;
+
+ @Override
+ protected void addServlets(ServletContextHandler servletContextHandler) throws ServletException {
+ // rwt-resources requires a file system
+ try {
+ Path tempDir = Files.createTempDirectory("argeo-rwtRunner");
+ servletContextHandler.setBaseResource(Resource.newResource(tempDir.resolve("www").toString()));
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot create temporary directory", e);
+ }
+ servletContextHandler.addEventListener(new ServletContextListener() {
+ ApplicationRunner applicationRunner;
+
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+ applicationRunner = new ApplicationRunner(cmsWebApp, sce.getServletContext());
+ applicationRunner.start();
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent sce) {
+ applicationRunner.stop();
+ }
+ });
+ for (String uiName : cmsWebApp.getCmsApp().getUiNames())
+ servletContextHandler.addServlet(new ServletHolder(new RWTServlet()), "/" + uiName);
+
+ // Required to serve rwt-resources. It is important that this is last.
+ ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
+ servletContextHandler.addServlet(holderPwd, "/");
+
+ }
+
+ public void setCmsWebApp(CmsWebApp cmsWebApp) {
+ this.cmsWebApp = cmsWebApp;
+ }
+
+}
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>org.argeo.cms.ui.rap</name>
+ <name>org.argeo.cms.swt.rap</name>
<comment></comment>
<projects>
</projects>
// log.debug("Published CMS web app /" + (contextName != null ? contextName : ""));
}
- CmsApp getCmsApp() {
+ public CmsApp getCmsApp() {
return cmsApp;
}