You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ja...@apache.org on 2014/05/07 15:53:42 UTC

svn commit: r1593017 - in /felix/trunk/http: itest/src/test/java/org/apache/felix/http/itest/ jetty/ jetty/src/main/java/org/apache/felix/http/jetty/ jetty/src/main/java/org/apache/felix/http/jetty/internal/

Author: jawi
Date: Wed May  7 13:53:41 2014
New Revision: 1593017

URL: http://svn.apache.org/r1593017
Log:
FELIX-4473 - allow custom Jetty Connectors:

- applied (cleaned up) patch from fmeschbe;
- added simple integration test to validate registration/deregistration.


Added:
    felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyConnectorTest.java   (with props)
    felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/ConnectorFactory.java   (with props)
    felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/ConnectorFactoryTracker.java   (with props)
    felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/package-info.java   (with props)
Modified:
    felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/AsyncTest.java
    felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java
    felix/trunk/http/jetty/pom.xml
    felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java

Modified: felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/AsyncTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/AsyncTest.java?rev=1593017&r1=1593016&r2=1593017&view=diff
==============================================================================
--- felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/AsyncTest.java (original)
+++ felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/AsyncTest.java Wed May  7 13:53:41 2014
@@ -47,7 +47,7 @@ public class AsyncTest extends BaseInteg
     /**
      * Tests that we can use an asynchronous servlet (introduced in Servlet 3.0 spec).
      */
-//    @Test
+    @Test
     public void testAsyncServletOk() throws Exception
     {
         CountDownLatch initLatch = new CountDownLatch(1);

Added: felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyConnectorTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyConnectorTest.java?rev=1593017&view=auto
==============================================================================
--- felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyConnectorTest.java (added)
+++ felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyConnectorTest.java Wed May  7 13:53:41 2014
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.itest;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.felix.http.jetty.ConnectorFactory;
+import org.eclipse.jetty.server.AbstractConnector;
+import org.eclipse.jetty.server.Connector;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@RunWith(JUnit4TestRunner.class)
+public class HttpJettyConnectorTest extends BaseIntegrationTest
+{
+    @Test
+    public void testRegisterConnectorFactoryOk() throws Exception
+    {
+        final CountDownLatch openLatch = new CountDownLatch(1);
+        final CountDownLatch closeLatch = new CountDownLatch(1);
+
+        ConnectorFactory factory = new ConnectorFactory()
+        {
+            @Override
+            public Connector createConnector()
+            {
+                return new AbstractConnector()
+                {
+                    @Override
+                    public void open() throws IOException
+                    {
+                        openLatch.countDown();
+                    }
+
+                    @Override
+                    public int getLocalPort()
+                    {
+                        return 8070;
+                    }
+
+                    @Override
+                    public Object getConnection()
+                    {
+                        return null;
+                    }
+
+                    @Override
+                    public void close() throws IOException
+                    {
+                        closeLatch.countDown();
+                    }
+
+                    @Override
+                    protected void accept(int acceptorID) throws IOException, InterruptedException
+                    {
+                        // nop
+                    }
+                };
+            }
+        };
+
+        ServiceRegistration reg = m_context.registerService(ConnectorFactory.class.getName(), factory, null);
+
+        // Should be opened automatically when picked up by the Jetty implementation...
+        assertTrue("Felix HTTP Jetty did not open the Connection or pick up the registered ConnectionFactory", openLatch.await(5, TimeUnit.SECONDS));
+
+        // Should close our connection...
+        reg.unregister();
+
+        assertTrue("Felix HTTP Jetty did not close the Connection", closeLatch.await(5, TimeUnit.SECONDS));
+    }
+}

Propchange: felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyConnectorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java?rev=1593017&r1=1593016&r2=1593017&view=diff
==============================================================================
--- felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java (original)
+++ felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java Wed May  7 13:53:41 2014
@@ -32,15 +32,19 @@ import java.io.IOException;
 import java.net.ConnectException;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
+import javax.servlet.Servlet;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -391,6 +395,39 @@ public class HttpJettyTest extends BaseI
         assertTrue(destroyLatch.await(5, TimeUnit.SECONDS));
     }
 
+    /**
+     * Tests that initialization parameters are properly passed.
+     */
+    @Test
+    public void testInitParametersOk() throws Exception
+    {
+        final CountDownLatch initLatch = new CountDownLatch(1);
+
+        Servlet servlet = new HttpServlet()
+        {
+            @Override
+            public void init(ServletConfig config) throws ServletException
+            {
+                String value1 = config.getInitParameter("key1");
+                String value2 = config.getInitParameter("key2");
+                if ("value1".equals(value1) && "value2".equals(value2))
+                {
+                    initLatch.countDown();
+                }
+            }
+        };
+
+        Dictionary params = new Hashtable();
+        params.put("key1", "value1");
+        params.put("key2", "value2");
+
+        getHttpService().registerServlet("/initTest", servlet, params, null);
+
+        assertTrue(initLatch.await(5, TimeUnit.SECONDS));
+
+        unregister(servlet);
+    }
+
     @Test
     public void testUseServletContextOk() throws Exception
     {

Modified: felix/trunk/http/jetty/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/http/jetty/pom.xml?rev=1593017&r1=1593016&r2=1593017&view=diff
==============================================================================
--- felix/trunk/http/jetty/pom.xml (original)
+++ felix/trunk/http/jetty/pom.xml Wed May  7 13:53:41 2014
@@ -55,7 +55,8 @@
                             org.apache.felix.http.jetty.internal.JettyActivator
                         </Bundle-Activator>
                         <Export-Package>
-        					org.eclipse.jetty.*;-split-package:=merge-first;version=${version;===;${jetty.version}}
+        					org.eclipse.jetty.*;-split-package:=merge-first;version=${version;===;${jetty.version}},
+                            org.apache.felix.http.jetty
                         </Export-Package>
                         <Private-Package>
                             org.apache.felix.http.base.*,
@@ -84,6 +85,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>biz.aQute</groupId>
+            <artifactId>bndlib</artifactId>
+            <version>1.50.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
             <scope>provided</scope>

Added: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/ConnectorFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/ConnectorFactory.java?rev=1593017&view=auto
==============================================================================
--- felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/ConnectorFactory.java (added)
+++ felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/ConnectorFactory.java Wed May  7 13:53:41 2014
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.jetty;
+
+import org.eclipse.jetty.server.Connector;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * The <code>ConnectorFactory</code> is a service interface which allows
+ * extensions to inject custom Jetty {@code Connector} instances to add
+ * to the Jetty server. Example connectors would be a SPDY connector or
+ * an SSL capable connector with a custom {@code SslContextFactory}.
+ * <p>
+ * {@code ConnectorFactory} services are responsible for creating the
+ * {@code Connector} instances and providing base configuration. Global
+ * configuration such as TCP/IP timeouts or buffer sizes are handled by the
+ * Jetty server launcher. Likewise the life cycle of the connectors is managed
+ * by the Jetty server and its launcher.
+ */
+@ConsumerType
+public interface ConnectorFactory
+{
+
+    /**
+     * Creates new Jetty {@code Connector} instances.
+     * <p>
+     * The instances must be configured. The Jetty server will additionally
+     * configure global configuration such as TCP/IP timeouts and buffer
+     * settings.
+     * <p>
+     * Connectors returned from this method are not started yet. Callers must
+     * add them to the Jetty server and start them.
+     * <p>
+     * If the {@code ConnectorFactory} service is stopped any connectors still
+     * active in Jetty servers must be stopped and removed from these Jetty
+     * servers.
+     *
+     * @return A configured Jetty {@code Connector} instance.
+     */
+    Connector createConnector();
+}

Propchange: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/ConnectorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/ConnectorFactoryTracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/ConnectorFactoryTracker.java?rev=1593017&view=auto
==============================================================================
--- felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/ConnectorFactoryTracker.java (added)
+++ felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/ConnectorFactoryTracker.java Wed May  7 13:53:41 2014
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.jetty.internal;
+
+import org.apache.felix.http.base.internal.logger.SystemLogger;
+import org.apache.felix.http.jetty.ConnectorFactory;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ConnectorFactoryTracker extends ServiceTracker
+{
+    private final Server server;
+
+    public ConnectorFactoryTracker(final BundleContext context, final Server server)
+    {
+        super(context, ConnectorFactory.class.getName(), null);
+        this.server = server;
+    }
+
+    @Override
+    public void open()
+    {
+        if (!this.server.isStarted())
+        {
+            throw new IllegalStateException("Jetty Server must be started before looking for ConnectorFactory services");
+        }
+
+        super.open();
+    }
+
+    @Override
+    public Object addingService(ServiceReference reference)
+    {
+        ConnectorFactory factory = (ConnectorFactory) super.addingService(reference);
+        Connector connector = factory.createConnector();
+        try
+        {
+            this.server.addConnector(connector);
+            connector.start();
+            return connector;
+        }
+        catch (Exception e)
+        {
+            SystemLogger.error("Failed starting connector '" + connector + "' provided by " + reference, e);
+        }
+
+        // connector failed to start, don't continue tracking
+        return null;
+    }
+
+    @Override
+    public void removedService(ServiceReference reference, Object service)
+    {
+        Connector connector = (Connector) service;
+        if (connector.isStarted())
+        {
+            try
+            {
+                connector.stop();
+            }
+            catch (Exception e)
+            {
+                SystemLogger.info("Failed stopping connector '" + connector + "' provided by " + reference + ": " + e);
+            }
+        }
+        this.server.removeConnector(connector);
+    }
+}

Propchange: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/ConnectorFactoryTracker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java?rev=1593017&r1=1593016&r2=1593017&view=diff
==============================================================================
--- felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java (original)
+++ felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java Wed May  7 13:53:41 2014
@@ -101,7 +101,8 @@ public final class JettyService extends 
     private EventDispatcher eventDispatcher;
     private MBeanServerTracker mbeanServerTracker;
     private BundleTracker bundleTracker;
-    private ServiceTracker serviceTracker;
+    private ServiceTracker eventAdmintTracker;
+    private ServiceTracker connectorTracker;
     private EventAdmin eventAdmin;
 
     public JettyService(BundleContext context, DispatcherServlet dispatcher, EventDispatcher eventDispatcher, HttpServiceController controller)
@@ -132,8 +133,8 @@ public final class JettyService extends 
         props.put(Constants.SERVICE_PID, PID);
         this.configServiceReg = this.context.registerService(ManagedService.class.getName(), new JettyManagedService(this), props);
 
-        this.serviceTracker = new ServiceTracker(this.context, EventAdmin.class.getName(), this);
-        this.serviceTracker.open();
+        this.eventAdmintTracker = new ServiceTracker(this.context, EventAdmin.class.getName(), this);
+        this.eventAdmintTracker.open();
 
         this.bundleTracker = new BundleTracker(this.context, Bundle.ACTIVE | Bundle.STARTING, this);
         this.bundleTracker.open();
@@ -151,10 +152,10 @@ public final class JettyService extends 
             this.bundleTracker.close();
             this.bundleTracker = null;
         }
-        if (this.serviceTracker != null)
+        if (this.eventAdmintTracker != null)
         {
-            this.serviceTracker.close();
-            this.serviceTracker = null;
+            this.eventAdmintTracker.close();
+            this.eventAdmintTracker = null;
         }
 
         // FELIX-4422: stop Jetty synchronously...
@@ -205,6 +206,11 @@ public final class JettyService extends 
     {
         if (this.server != null)
         {
+            if (this.connectorTracker != null)
+            {
+                this.connectorTracker.close();
+                this.connectorTracker = null;
+            }
             try
             {
                 this.server.stop();
@@ -268,6 +274,9 @@ public final class JettyService extends 
                 message.append(" HTTPS:").append(this.config.getHttpsPort());
             }
 
+            this.connectorTracker = new ConnectorFactoryTracker(this.context, this.server);
+            this.connectorTracker.open();
+
             if (this.server.getConnectors() != null && this.server.getConnectors().length > 0)
             {
                 message.append(" on context path ").append(this.config.getContextPath());

Added: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/package-info.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/package-info.java?rev=1593017&view=auto
==============================================================================
--- felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/package-info.java (added)
+++ felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/package-info.java Wed May  7 13:53:41 2014
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+@Version("1.0")
+package org.apache.felix.http.jetty;
+
+import aQute.bnd.annotation.Version;
\ No newline at end of file

Propchange: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native