You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2012/06/08 11:20:55 UTC

svn commit: r1347965 - in /camel/trunk/components/camel-websocket/src: main/java/org/apache/camel/component/websocket/WebsocketComponent.java main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java test/resources/log4j.properties

Author: davsclaus
Date: Fri Jun  8 09:20:55 2012
New Revision: 1347965

URL: http://svn.apache.org/viewvc?rev=1347965&view=rev
Log:
CAMEL-5280: Fixed camel-websocket to work with static resource server again.

Modified:
    camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java
    camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java
    camel/trunk/components/camel-websocket/src/test/resources/log4j.properties

Modified: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java?rev=1347965&r1=1347964&r2=1347965&view=diff
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java (original)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketComponent.java Fri Jun  8 09:20:55 2012
@@ -16,30 +16,20 @@
  */
 package org.apache.camel.component.websocket;
 
-import java.io.IOException;
-import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
-import java.net.URI;
-import java.security.GeneralSecurityException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import javax.management.MBeanServer;
-import javax.servlet.Servlet;
 
-import org.apache.camel.Component;
-import org.apache.camel.Consumer;
 import org.apache.camel.Endpoint;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.ManagementAgent;
 import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.URISupport;
-import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.apache.camel.util.jsse.SSLContextParameters;
 import org.eclipse.jetty.http.ssl.SslContextFactory;
 import org.eclipse.jetty.jmx.MBeanContainer;
@@ -71,20 +61,25 @@ public class WebsocketComponent extends 
     protected SSLContextParameters sslContextParameters;
     protected MBeanContainer mbContainer;
     protected ThreadPool threadPool;
-    protected ServletContextHandler context;
 
-    protected Integer port;
+    protected Integer port = 9292;
     protected Integer minThreads;
     protected Integer maxThreads;
 
     protected boolean enableJmx;
 
-    protected String host;
+    protected String host = "0.0.0.0";
     protected String staticResources;
+    protected Server staticResourcesServer;
     protected String sslKeyPassword;
     protected String sslPassword;
     protected String sslKeystore;
 
+    /**
+     * Map for storing servlets. {@link WebsocketComponentServlet} is identified by pathSpec {@link String}.
+     */
+    private Map<String, WebsocketComponentServlet> servlets = new HashMap<String, WebsocketComponentServlet>();
+
     class ConnectorRef {
         Server server;
         Connector connector;
@@ -111,22 +106,15 @@ public class WebsocketComponent extends 
         }
     }
 
-    /**
-     * Map for storing servlets. {@link WebsocketComponentServlet} is identified by pathSpec {@link String}.
-     */
-    private Map<String, WebsocketComponentServlet> servlets = new HashMap<String, WebsocketComponentServlet>();
-
     public WebsocketComponent() {
     }
 
-
     /**
      * Connects the URL specified on the endpoint to the specified processor.
      */
     public void connect(WebsocketProducerConsumer prodcon) throws Exception {
 
         Server server = null;
-        String baseResource = null;
         WebsocketEndpoint endpoint = prodcon.getEndpoint();
 
         String connectorKey = getConnectorKey(endpoint);
@@ -141,42 +129,18 @@ public class WebsocketComponent extends 
                     connector = new SelectChannelConnector();
                 }
 
-                LOG.debug("Jetty Connector added : " + connector.getName());
+                LOG.trace("Jetty Connector added: {}", connector.getName());
 
-                if (port != null) {
-                    connector.setPort(port);
-                } else {
+                if (endpoint.getPort() != null) {
                     connector.setPort(endpoint.getPort());
-                }
-
-                if (host != null) {
-                    connector.setHost(host);
                 } else {
-                    connector.setHost(endpoint.getHost());
+                    connector.setPort(port);
                 }
 
-                connector.setHost(endpoint.getHost());
-
-                // TODO -  Is it the right place to define static resources ?
-                if (endpoint.getHome() != null) {
-
-                    ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.NO_SECURITY | ServletContextHandler.NO_SESSIONS);
-
-                    if (endpoint.getHome().startsWith("classpath:")) {
-                        baseResource = ObjectHelper.after(endpoint.getHome(), "classpath:");
-                        LOG.debug("Using base resource from classpath: {}", baseResource);
-                        context.setBaseResource(new JettyClassPathResource(getCamelContext().getClassResolver(), baseResource));
-                    } else {
-                        LOG.debug("Using base resource: {}", baseResource);
-                        context.setResourceBase(baseResource);
-                    }
-                    DefaultServlet defaultServlet = new DefaultServlet();
-                    ServletHolder holder = new ServletHolder(defaultServlet);
-
-                    // avoid file locking on windows
-                    // http://stackoverflow.com/questions/184312/how-to-make-jetty-dynamically-load-static-pages
-                    holder.setInitParameter("useFileMappedBuffer", "false");
-                    context.addServlet(holder, "/");
+                if (endpoint.getHost() != null) {
+                    connector.setHost(endpoint.getHost());
+                } else {
+                    connector.setHost(host);
                 }
 
                 // Create Server and add connector
@@ -184,11 +148,10 @@ public class WebsocketComponent extends 
                 if (endpoint.isEnableJmx()) {
                     enableJmx(server);
                 }
-
                 server.addConnector(connector);
 
-                // Create ServletContextHandler and add it to the Jetty server
-                context = createContext(server, connector, endpoint.getHandlers());
+                // Create ServletContextHandler
+                ServletContextHandler context = createContext(server, connector, endpoint.getHandlers());
                 server.setHandler(context);
 
                 // Don't provide a Servlet object as Producer/Consumer will create them later on
@@ -198,13 +161,11 @@ public class WebsocketComponent extends 
                 if (endpoint.isSessionSupport()) {
                     enableSessionSupport(connectorRef.server, connectorKey);
                 }
+                LOG.info("Jetty Server starting on host: {}:{}", connector.getHost(), connector.getPort());
                 connectorRef.server.start();
 
                 CONNECTORS.put(connectorKey, connectorRef);
 
-                LOG.debug("Jetty Server started for host : " + connector.getHost() + ", on port : " + connector.getPort());
-                server.start();
-
             } else {
                 connectorRef.increment();
             }
@@ -214,12 +175,10 @@ public class WebsocketComponent extends 
                 enableSessionSupport(connectorRef.server, connectorKey);
             }
 
-            // TODO - chm - 25/05
-            // As we can define WebSocket for Consumer/Producer
-            // This part of the code must be adapted compare to camel-jetty where we only use
-            // Jetty as a server = Consumer
-            // connectorRef.servlet.connect(consumer);
-
+            if (prodcon instanceof WebsocketConsumer) {
+                // connect websocket consumer, to servlet
+                connectorRef.servlet.connect((WebsocketConsumer) prodcon);
+            }
         }
 
     }
@@ -238,7 +197,10 @@ public class WebsocketComponent extends 
             if (connectorRef != null) {
                 if (connectorRef.decrement() == 0) {
                     connectorRef.server.removeConnector(connectorRef.connector);
-                    connectorRef.connector.stop();
+                    if (connectorRef.connector != null) {
+                        // static server may not have set a connector
+                        connectorRef.connector.stop();
+                    }
                     connectorRef.server.stop();
                     CONNECTORS.remove(connectorKey);
                     // Camel controls the lifecycle of these entities so remove the
@@ -248,6 +210,9 @@ public class WebsocketComponent extends 
                         mbContainer.removeBean(connectorRef.connector);
                     }
                 }
+                if (prodcon instanceof WebsocketConsumer) {
+                    connectorRef.servlet.disconnect((WebsocketConsumer) prodcon);
+                }
             }
         }
     }
@@ -277,8 +242,6 @@ public class WebsocketComponent extends 
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
 
-        Map<String, Object> websocketParameters = new HashMap<String, Object>(parameters);
-
         Boolean enableJmx = getAndRemoveParameter(parameters, "enableJmx", Boolean.class);
         SSLContextParameters sslContextParameters = resolveAndRemoveReferenceParameter(parameters, "sslContextParametersRef", SSLContextParameters.class);
         int port = extractPortNumber(remaining);
@@ -338,13 +301,49 @@ public class WebsocketComponent extends 
         return server;
     }
 
+    protected Server createStaticResourcesServer(ServletContextHandler context, String host, int port, String home) {
+        Server server = new Server();
+
+        Connector connector = new SelectChannelConnector();
+        connector.setHost(host);
+        connector.setPort(port);
+        server.addConnector(connector);
+
+        context.setContextPath("/");
+
+        SessionManager sm = new HashSessionManager();
+        SessionHandler sh = new SessionHandler(sm);
+        context.setSessionHandler(sh);
+
+        if (home != null) {
+            if (home.startsWith("classpath:")) {
+                home = ObjectHelper.after(home, "classpath:");
+                LOG.debug("Using base resource from classpath: {}", home);
+                context.setBaseResource(new JettyClassPathResource(getCamelContext().getClassResolver(), home));
+            } else {
+                LOG.debug("Using base resource: {}", home);
+                context.setResourceBase(home);
+            }
+            DefaultServlet defaultServlet = new DefaultServlet();
+            ServletHolder holder = new ServletHolder(defaultServlet);
+
+            // avoid file locking on windows
+            // http://stackoverflow.com/questions/184312/how-to-make-jetty-dynamically-load-static-pages
+            holder.setInitParameter("useFileMappedBuffer", "false");
+            context.addServlet(holder, "/");
+        }
+
+        server.setHandler(context);
+
+        return server;
+    }
+
     protected WebsocketComponentServlet addServlet(NodeSynchronization sync, WebsocketProducer producer, String remaining) throws Exception {
 
         // Get Connector from one of the Jetty Instances to add WebSocket Servlet
         WebsocketEndpoint endpoint = producer.getEndpoint();
-        WebsocketComponent component = endpoint.getComponent();
         String key = getConnectorKey(endpoint);
-        ConnectorRef connectorRef = component.getConnectors().get(key);
+        ConnectorRef connectorRef = getConnectors().get(key);
 
         WebsocketComponentServlet servlet;
 
@@ -358,21 +357,18 @@ public class WebsocketComponent extends 
                 connectorRef.servlet = servlet;
                 LOG.debug("WebSocket servlet added for the following path : " + pathSpec + ", to the Jetty Server : " + key);
             }
-
             return servlet;
         } else {
             throw new Exception("Jetty instance has not been retrieved for : " + key);
         }
-
     }
 
     protected WebsocketComponentServlet addServlet(NodeSynchronization sync, WebsocketConsumer consumer, String remaining) throws Exception {
 
         // Get Connector from one of the Jetty Instances to add WebSocket Servlet
         WebsocketEndpoint endpoint = consumer.getEndpoint();
-        WebsocketComponent component = endpoint.getComponent();
         String key = getConnectorKey(endpoint);
-        ConnectorRef connectorRef = component.getConnectors().get(key);
+        ConnectorRef connectorRef = getConnectors().get(key);
 
         WebsocketComponentServlet servlet;
 
@@ -388,20 +384,13 @@ public class WebsocketComponent extends 
                 LOG.debug("WebSocket servlet added for the following path : " + pathSpec + ", to the Jetty Server : " + key);
             }
 
-            if (consumer != null) {
-                if (servlet.getConsumer() == null)  {
-                    // TODO - chm - 25/05
-                    // Why do we have to do a setConsumer on the Servlet ?
-                    servlet.setConsumer(consumer);
-                }
-
+            if (servlet.getConsumer() == null)  {
+                servlet.setConsumer(consumer);
             }
-
             return servlet;
         } else {
             throw new Exception("Jetty instance has not been retrieved for : " + key);
         }
-
     }
 
     protected WebsocketComponentServlet createServlet(NodeSynchronization sync, String pathSpec, Map<String, WebsocketComponentServlet> servlets, ServletContextHandler handler) {
@@ -411,7 +400,6 @@ public class WebsocketComponent extends 
         return servlet;
     }
 
-
     protected ServletContextHandler createContext(Server server, Connector connector, List<Handler> handlers) throws Exception {
         ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.NO_SECURITY | ServletContextHandler.NO_SESSIONS);
         context.setConnectorNames(new String[] {connector.getName()});
@@ -430,9 +418,7 @@ public class WebsocketComponent extends 
             }
         }
 
-        this.context = context;
         return context;
-
     }
 
     /**
@@ -491,7 +477,6 @@ public class WebsocketComponent extends 
         return sslSocketConnector;
     }
 
-
     /**
      * Override the key/trust store check method as it does not account for a factory that has
      * a pre-configured {@link javax.net.ssl.SSLContext}.
@@ -541,7 +526,7 @@ public class WebsocketComponent extends 
         }
     }
 
-    private static int extractPortNumber(String remaining) {
+    private int extractPortNumber(String remaining) {
         int index1 = remaining.indexOf(":");
         int index2 = remaining.indexOf("/");
 
@@ -549,19 +534,17 @@ public class WebsocketComponent extends 
             String result = remaining.substring(index1 + 1, index2);
             return Integer.parseInt(result);
         } else {
-            return 9292;
+            return port;
         }
-
     }
 
-    private static String extractHostName(String remaining) {
+    private String extractHostName(String remaining) {
         int index = remaining.indexOf(":");
         if (index != -1) {
             return remaining.substring(0, index);
         } else {
-            return null;
+            return host;
         }
-
     }
 
     private String getConnectorKey(WebsocketEndpoint endpoint) {
@@ -683,20 +666,31 @@ public class WebsocketComponent extends 
         this.sslContextParameters = sslContextParameters;
     }
 
-    public ServletContextHandler getContext() {
-        return context;
-    }
-
     public static HashMap<String, ConnectorRef> getConnectors() {
         return CONNECTORS;
     }
 
-
     @Override
     protected void doStart() throws Exception {
         super.doStart();
-        //LOG.info("Starting server {}:{}; static resources: {}", new Object[]{host, port, staticResources});
-        //server = createServer(context, host, port, staticResources);
+
+        if (staticResources != null) {
+            // host and port must be configured
+            ObjectHelper.notEmpty(host, "host", this);
+            ObjectHelper.notNull(port, "port", this);
+
+            LOG.info("Starting static resources server {}:{} with static resource: {}", new Object[]{host, port, staticResources});
+            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+            staticResourcesServer = createStaticResourcesServer(context, host, port, staticResources);
+            staticResourcesServer.start();
+            Connector connector = staticResourcesServer.getConnectors()[0];
+
+            // must add static resource server to CONNECTORS in case the websocket producers/consumers
+            // uses the same port number, and therefore we must be part of this
+            ConnectorRef ref = new ConnectorRef(staticResourcesServer, connector, null);
+            String key = "websocket:" + host + ":" + port;
+            CONNECTORS.put(key, ref);
+        }
     }
 
     @Override
@@ -709,11 +703,21 @@ public class WebsocketComponent extends 
                     connectorRef.server.removeConnector(connectorRef.connector);
                     connectorRef.connector.stop();
                     connectorRef.server.stop();
+                    connectorRef.servlet = null;
                 }
                 CONNECTORS.remove(connectorKey);
             }
         }
+        CONNECTORS.clear();
+
+        if (staticResourcesServer != null) {
+            LOG.info("Stopping static resources server {}:{} with static resource: {}", new Object[]{host, port, staticResources});
+            staticResourcesServer.stop();
+            staticResourcesServer.destroy();
+            staticResourcesServer = null;
+        }
 
+        servlets.clear();
     }
 }
 

Modified: camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java?rev=1347965&r1=1347964&r2=1347965&view=diff
==============================================================================
--- camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java (original)
+++ camel/trunk/components/camel-websocket/src/main/java/org/apache/camel/component/websocket/WebsocketEndpoint.java Fri Jun  8 09:20:55 2012
@@ -82,30 +82,23 @@ public class WebsocketEndpoint extends D
     }
 
     public void connect(WebsocketConsumer consumer) throws Exception {
-        // Jetty instance will be created
-        // if it does not exist
         component.connect(consumer);
-
-        // We will add a WebSocket servlet
-        // to a Jetty server using Handler
-        getComponent().addServlet(sync, consumer, remaining);
+        component.addServlet(sync, consumer, remaining);
     }
 
     public void disconnect(WebsocketConsumer consumer) throws Exception {
         component.disconnect(consumer);
         // Servlet should be removed
-        // getComponent().addServlet(sync, consumer, remaining);
     }
 
     public void connect(WebsocketProducer producer) throws Exception {
         component.connect(producer);
-        getComponent().addServlet(sync, producer, remaining);
+        component.addServlet(sync, producer, remaining);
     }
 
     public void disconnect(WebsocketProducer producer) throws Exception {
         component.disconnect(producer);
         // Servlet should be removed
-        // getComponent().addServlet(sync, consumer, remaining);
     }
 
     @Override

Modified: camel/trunk/components/camel-websocket/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-websocket/src/test/resources/log4j.properties?rev=1347965&r1=1347964&r2=1347965&view=diff
==============================================================================
--- camel/trunk/components/camel-websocket/src/test/resources/log4j.properties (original)
+++ camel/trunk/components/camel-websocket/src/test/resources/log4j.properties Fri Jun  8 09:20:55 2012
@@ -22,9 +22,9 @@ log4j.rootLogger=INFO, file
 
 # uncomment the following line to turn on Camel debugging
 log4j.logger.org.apache.camel.component.websocket=DEBUG
-log4j.logger.org.eclipse.jetty.websocket=DEBUG
-log4j.logger.org.eclipse.jetty=DEBUG
-log4j.logger.com.ning.http.client=DEBUG
+#log4j.logger.org.eclipse.jetty.websocket=DEBUG
+#log4j.logger.org.eclipse.jetty=DEBUG
+#log4j.logger.com.ning.http.client=DEBUG
 
 
 # CONSOLE appender not used by default