You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2017/04/24 16:23:41 UTC
svn commit: r1792513 - in
/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal:
dispatch/Dispatcher.java service/HttpServiceRuntimeImpl.java
whiteboard/WhiteboardManager.java
Author: cziegeler
Date: Mon Apr 24 16:23:40 2017
New Revision: 1792513
URL: http://svn.apache.org/viewvc?rev=1792513&view=rev
Log:
FELIX-5296 : Implement Http Whiteboard Service Updates (RFC 223)
Modified:
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java?rev=1792513&r1=1792512&r2=1792513&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java Mon Apr 24 16:23:40 2017
@@ -21,6 +21,7 @@ import java.util.Set;
import javax.annotation.CheckForNull;
import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
@@ -38,6 +39,7 @@ import org.apache.felix.http.base.intern
import org.apache.felix.http.base.internal.registry.PathResolution;
import org.apache.felix.http.base.internal.registry.PerContextHandlerRegistry;
import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
+import org.osgi.service.http.whiteboard.Preprocessor;
public final class Dispatcher
{
@@ -85,70 +87,80 @@ public final class Dispatcher
mgr.sessionDestroyed(session, ids);
}
- // invoke preprocessors
- if ( !mgr.invokePreprocessors(req, res) )
- {
- return;
- }
-
- // get full decoded path for dispatching
- // we can't use req.getRequestURI() or req.getRequestURL() as these are returning the encoded path
- String path = req.getServletPath();
- if ( path == null )
- {
- path = "";
- }
- if ( req.getPathInfo() != null )
- {
- path = path.concat(req.getPathInfo());
- }
- final String requestURI = path;
-
- // Determine which servlet we should forward the request to...
- final PathResolution pr = this.handlerRegistry.resolveServlet(requestURI);
+ // invoke preprocessors and then dispatching
+ mgr.invokePreprocessors(req, res, new Preprocessor() {
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ // get full decoded path for dispatching
+ // we can't use req.getRequestURI() or req.getRequestURL() as these are returning the encoded path
+ String path = req.getServletPath();
+ if ( path == null )
+ {
+ path = "";
+ }
+ if ( req.getPathInfo() != null )
+ {
+ path = path.concat(req.getPathInfo());
+ }
+ final String requestURI = path;
+
+ // Determine which servlet we should forward the request to...
+ final PathResolution pr = handlerRegistry.resolveServlet(requestURI);
+
+ final PerContextHandlerRegistry errorRegistry = (pr != null ? pr.handlerRegistry : handlerRegistry.getBestMatchingRegistry(requestURI));
+ final String servletName = (pr != null ? pr.handler.getName() : null);
+ final HttpServletResponse wrappedResponse = new ServletResponseWrapper(req, res, servletName, errorRegistry);
+ if ( pr == null )
+ {
+ wrappedResponse.sendError(404);
+ return;
+ }
+
+ final ExtServletContext servletContext = pr.handler.getContext();
+ final RequestInfo requestInfo = new RequestInfo(pr.servletPath, pr.pathInfo, null, req.getRequestURI());
+
+ final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo, null,
+ pr.handler.getContextServiceId(),
+ pr.handler.getServletInfo().isAsyncSupported(),
+ pr.handler.getServletInfo().getMultipartConfig());
+ final FilterHandler[] filterHandlers = handlerRegistry.getFilters(pr, req.getDispatcherType(), pr.requestURI);
+
+ try
+ {
+ if ( servletContext.getServletRequestListener() != null )
+ {
+ servletContext.getServletRequestListener().requestInitialized(new ServletRequestEvent(servletContext, wrappedRequest));
+ }
+ final FilterChain filterChain = new InvocationChain(pr.handler, filterHandlers);
+ filterChain.doFilter(wrappedRequest, wrappedResponse);
+
+ }
+ catch ( final Exception e)
+ {
+ SystemLogger.error("Exception while processing request to " + requestURI, e);
+ req.setAttribute(RequestDispatcher.ERROR_EXCEPTION, e);
+ req.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, e.getClass().getName());
+
+ wrappedResponse.sendError(500);
+ }
+ finally
+ {
+ if ( servletContext.getServletRequestListener() != null )
+ {
+ servletContext.getServletRequestListener().requestDestroyed(new ServletRequestEvent(servletContext, wrappedRequest));
+ }
+ } }
+
+ @Override
+ public void destroy() {
+ }
+ });
- final PerContextHandlerRegistry errorRegistry = (pr != null ? pr.handlerRegistry : this.handlerRegistry.getBestMatchingRegistry(requestURI));
- final String servletName = (pr != null ? pr.handler.getName() : null);
- final HttpServletResponse wrappedResponse = new ServletResponseWrapper(req, res, servletName, errorRegistry);
- if ( pr == null )
- {
- wrappedResponse.sendError(404);
- return;
- }
-
- final ExtServletContext servletContext = pr.handler.getContext();
- final RequestInfo requestInfo = new RequestInfo(pr.servletPath, pr.pathInfo, null, req.getRequestURI());
-
- final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo, null,
- pr.handler.getContextServiceId(),
- pr.handler.getServletInfo().isAsyncSupported(),
- pr.handler.getServletInfo().getMultipartConfig());
- final FilterHandler[] filterHandlers = this.handlerRegistry.getFilters(pr, req.getDispatcherType(), pr.requestURI);
-
- try
- {
- if ( servletContext.getServletRequestListener() != null )
- {
- servletContext.getServletRequestListener().requestInitialized(new ServletRequestEvent(servletContext, wrappedRequest));
- }
- final FilterChain filterChain = new InvocationChain(pr.handler, filterHandlers);
- filterChain.doFilter(wrappedRequest, wrappedResponse);
-
- }
- catch ( final Exception e)
- {
- SystemLogger.error("Exception while processing request to " + requestURI, e);
- req.setAttribute(RequestDispatcher.ERROR_EXCEPTION, e);
- req.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, e.getClass().getName());
-
- wrappedResponse.sendError(500);
- }
- finally
- {
- if ( servletContext.getServletRequestListener() != null )
- {
- servletContext.getServletRequestListener().requestDestroyed(new ServletRequestEvent(servletContext, wrappedRequest));
- }
- }
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java?rev=1792513&r1=1792512&r2=1792513&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java Mon Apr 24 16:23:40 2017
@@ -27,6 +27,7 @@ import org.apache.felix.http.base.intern
import org.apache.felix.http.base.internal.runtime.dto.RequestInfoDTOBuilder;
import org.apache.felix.http.base.internal.runtime.dto.RuntimeDTOBuilder;
import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
+import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.runtime.HttpServiceRuntime;
@@ -40,8 +41,10 @@ public final class HttpServiceRuntimeImp
* a dependency on R7 of the framework.
* The value of the property is of type {@code Long}.
*/
- private static String PROP_CHANGECOUNT = "service.changecount";
+ private static final String PROP_CHANGECOUNT = "service.changecount";
+ private static final String PROP_CHANGECOUNTDELAY = "org.apache.felix.http.whiteboard.changecount.delay";
+
private volatile Hashtable<String, Object> attributes = new Hashtable<String, Object>();
private final HandlerRegistry registry;
@@ -53,11 +56,32 @@ public final class HttpServiceRuntimeImp
private volatile Timer timer;
+ private final long updateChangeCountDelay;
+
public HttpServiceRuntimeImpl(HandlerRegistry registry,
- WhiteboardManager contextManager)
+ WhiteboardManager contextManager,
+ BundleContext bundleContext)
{
this.registry = registry;
this.contextManager = contextManager;
+ final Object val = bundleContext.getProperty(PROP_CHANGECOUNTDELAY);
+ long value = 2000L;
+ if ( val != null )
+ {
+ try
+ {
+ value = Long.parseLong(val.toString());
+ }
+ catch ( final NumberFormatException nfe)
+ {
+ // ignore
+ }
+ if ( value < 1 )
+ {
+ value = 0L;
+ }
+ }
+ updateChangeCountDelay = value;
}
@Override
@@ -113,27 +137,35 @@ public final class HttpServiceRuntimeImp
this.changeCount++;
count = this.changeCount;
this.setAttribute(PROP_CHANGECOUNT, this.changeCount);
- if ( this.timer == null )
+ if ( this.updateChangeCountDelay > 0 && this.timer == null )
{
this.timer = new Timer();
}
}
- timer.schedule(new TimerTask()
+ if ( this.updateChangeCountDelay == 0L )
{
-
- @Override
- public void run() {
- synchronized ( HttpServiceRuntimeImpl.this )
- {
- if ( changeCount == count )
- {
- reg.setProperties(getAttributes());
- timer.cancel();
- timer = null;
- }
- }
- }
- }, 2000L);
+ reg.setProperties(getAttributes());
+ }
+ else
+ {
+ timer.schedule(new TimerTask()
+ {
+
+ @Override
+ public void run()
+ {
+ synchronized ( HttpServiceRuntimeImpl.this )
+ {
+ if ( changeCount == count )
+ {
+ reg.setProperties(getAttributes());
+ timer.cancel();
+ timer = null;
+ }
+ }
+ }
+ }, this.updateChangeCountDelay);
+ }
}
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java?rev=1792513&r1=1792512&r2=1792513&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java Mon Apr 24 16:23:40 2017
@@ -97,6 +97,7 @@ import org.osgi.service.http.runtime.dto
import org.osgi.service.http.runtime.dto.PreprocessorDTO;
import org.osgi.service.http.runtime.dto.ServletContextDTO;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
+import org.osgi.service.http.whiteboard.Preprocessor;
import org.osgi.util.tracker.ServiceTracker;
public final class WhiteboardManager
@@ -145,7 +146,7 @@ public final class WhiteboardManager
this.httpBundleContext = bundleContext;
this.httpServiceFactory = httpServiceFactory;
this.registry = registry;
- this.serviceRuntime = new HttpServiceRuntimeImpl(registry, this);
+ this.serviceRuntime = new HttpServiceRuntimeImpl(registry, this, bundleContext);
this.plugin = new HttpServicePlugin(bundleContext, this.serviceRuntime);
}
@@ -982,35 +983,41 @@ public final class WhiteboardManager
* @throws IOException
* @throws ServletException
*/
- public boolean invokePreprocessors(final HttpServletRequest req, final HttpServletResponse res)
+ public void invokePreprocessors(final HttpServletRequest req,
+ final HttpServletResponse res,
+ final Preprocessor dispatcher)
throws ServletException, IOException
{
final List<PreprocessorHandler> localHandlers = this.preprocessorHandlers;
if ( localHandlers.isEmpty() )
{
- return true;
+ // no preprocessors, we can directly execute
+ dispatcher.doFilter(req, res, null);
}
- final AtomicBoolean result = new AtomicBoolean(true);
- final FilterChain chain = new FilterChain()
- {
-
- @Override
- public void doFilter(final ServletRequest request, final ServletResponse response)
- throws IOException, ServletException
- {
- result.set(true);
- }
- };
- for(final PreprocessorHandler handler : localHandlers)
+ else
{
- result.set(false);
- handler.handle(req, res, chain);
- if ( !result.get() )
- {
- break;
- }
+ final FilterChain chain = new FilterChain()
+ {
+ private int index = 0;
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response)
+ throws IOException, ServletException
+ {
+ if ( index == localHandlers.size() )
+ {
+ dispatcher.doFilter(request, response, null);
+ }
+ else
+ {
+ final PreprocessorHandler handler = localHandlers.get(index);
+ index++;
+ handler.handle(request, response, this);
+ }
+ }
+ };
+ chain.doFilter(req, res);
}
- return result.get();
}
private void updateRuntimeChangeCount()