FELIX-4863 : SSLFilter 0.1.0 and 0.2.0 have a Java race condition, stopping the Filter from working correctly
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1676455 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/HttpServiceTracker.java b/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/HttpServiceTracker.java
index b9b7576..f8fb312 100644
--- a/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/HttpServiceTracker.java
+++ b/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/HttpServiceTracker.java
@@ -18,12 +18,8 @@
*/
package org.apache.felix.http.sslfilter.internal;
-import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import javax.servlet.ServletException;
@@ -44,37 +40,39 @@
*/
public class HttpServiceTracker extends ServiceTracker
{
- private final ConcurrentMap<ServiceReference, SslFilter> filters;
+ /** Singleton filter to be registered with all http services. */
+ private final SslFilter filter = new SslFilter();
- private ServiceRegistration configReceiver;
+ private volatile ServiceRegistration configReceiver;
@SuppressWarnings("serial")
- public HttpServiceTracker(BundleContext context)
+ public HttpServiceTracker(final BundleContext context)
{
super(context, ExtHttpService.class.getName(), null);
-
- this.filters = new ConcurrentHashMap<ServiceReference, SslFilter>();
}
@Override
- public void open(boolean trackAllServices)
+ public void open(final boolean trackAllServices)
{
- Dictionary<String, Object> props = new Hashtable<String, Object>();
+ final Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put(Constants.SERVICE_PID, SslFilter.PID);
this.configReceiver = super.context.registerService(ManagedService.class.getName(), new ServiceFactory()
{
+ @Override
public Object getService(Bundle bundle, ServiceRegistration registration)
{
return new ManagedService()
{
+ @Override
public void updated(@SuppressWarnings("rawtypes") Dictionary properties) throws ConfigurationException
{
configureFilters(properties);
}
};
}
-
+
+ @Override
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service)
{
// Nop
@@ -96,18 +94,16 @@
}
}
- public Object addingService(ServiceReference reference)
+ @Override
+ public Object addingService(final ServiceReference reference)
{
- ExtHttpService service = (ExtHttpService) super.addingService(reference);
+ final ExtHttpService service = (ExtHttpService) super.addingService(reference);
if (service != null)
{
- SslFilter filter = new SslFilter();
try
{
service.registerFilter(filter, ".*", new Hashtable(), 0, null);
- this.filters.putIfAbsent(reference, filter);
-
SystemLogger.log(LogService.LOG_DEBUG, "SSL filter registered...");
}
catch (ServletException e)
@@ -119,25 +115,18 @@
return service;
}
- public void removedService(ServiceReference reference, Object service)
+ @Override
+ public void removedService(final ServiceReference reference, final Object service)
{
- SslFilter filter = this.filters.remove(reference);
- if (filter != null)
- {
- ((ExtHttpService) service).unregisterFilter(filter);
+ ((ExtHttpService) service).unregisterFilter(filter);
- SystemLogger.log(LogService.LOG_DEBUG, "SSL filter unregistered...");
- }
+ SystemLogger.log(LogService.LOG_DEBUG, "SSL filter unregistered...");
super.removedService(reference, service);
}
void configureFilters(@SuppressWarnings("rawtypes") final Dictionary properties) throws ConfigurationException
{
- List<SslFilter> filters = new ArrayList<SslFilter>(this.filters.values());
- for (SslFilter sslFilter : filters)
- {
- sslFilter.configure(properties);
- }
+ this.filter.configure(properties);
}
}
diff --git a/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/LogServiceTracker.java b/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/LogServiceTracker.java
index 87b8909..ab06dbb 100644
--- a/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/LogServiceTracker.java
+++ b/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/LogServiceTracker.java
@@ -24,6 +24,8 @@
import org.osgi.util.tracker.ServiceTracker;
/**
+ * TODO - this implementation assumes that there is exactly one LogService
+ *
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class LogServiceTracker extends ServiceTracker
diff --git a/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/SslFilterActivator.java b/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/SslFilterActivator.java
index d4f36da..db72c3b 100644
--- a/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/SslFilterActivator.java
+++ b/http/sslfilter/src/main/java/org/apache/felix/http/sslfilter/internal/SslFilterActivator.java
@@ -26,7 +26,8 @@
private HttpServiceTracker httpTracker;
private LogServiceTracker logTracker;
- public void start(BundleContext context)
+ @Override
+ public void start(final BundleContext context)
{
this.logTracker = new LogServiceTracker(context);
this.logTracker.open();
@@ -35,7 +36,8 @@
this.httpTracker.open();
}
- public void stop(BundleContext context)
+ @Override
+ public void stop(final BundleContext context)
{
if (this.httpTracker != null)
{