Hi List, we had a fierce discussion on the current HttpContext approach which at present is kind of broken. Here are my notes.
Regards, Bram ---------------------------------------- |Analysis of org.amdatu.web.httpcontext| ---------------------------------------- Summarized: In the process of implementing dispatcher we ran into problems with the current approach to HttpContext handling design and limitations of the implementation. This analysis proposes a new cleaner and more powerfull approach making life easier for developers. Analysis of HttpContext usage in Amdatu: HttpContext is the OSGi http extention to ServletContext. It is intended to delegated resource loading, security checking an mimetype checking to a service. The spec says that servlets (spec does not know about filters) that share the same HttpContext share the same ServletContext. In Amdatu this HttpContext could be used to support handling these (partially) croscutting concerns for a logical set of servlet and filters, for example (a tenant instance of) an application. For example, application RedDwarf containing could use one HttpContext for handling security of all requests to all (or a subset of) its resources. However, as applications typically consist of multiple (small) bundles, like gadgets, resource loading quickly becomes less straight forward as resources (like images) may come from different bundles. This means that simple application code would nee to do complex administration across bundles. Therefore we aim to provide a more convenient solution. Use cases: 1) A set of servlets/filters wish to share a HttpContext without resources or security 2) A set of servlets/filters wish to share a HttpContext with resources without security 3) A set of servlets/filters wish to share a HttpContext without resources with security 4) A set of servlets/filters wish to share a HttpContext with resources and security In an attempt to address these concerns the current implemetation provides a HttpContextFactory service where HttpContext instances can be create by providing a BundleContext and a ResourceProvider. The factory creates the HttpContext that delagets resource laoding to the ResourceProvider and then registers it as a service under the callers BundleContext. In addition the jsp support bundle looks for ResourceProvider registration and provides JSPServlet registration for them. This is a convienience mechanism. Problems with current implementation: The HttpContextServiceFactory is not whiteboard style. Consumer must call the service to create a HttpContext passing their BundleContext and optionally a ResourceProvider. The HttpContextServiceFactory directly calls HttpService registerResources for each ResourceProvider, again not whiteboard and preventing us from getting in between with a Dispatcher / TenantResolver. Unlike what the javadoc says a HttpContext does not support multiple ResourceProviders because although intended it turned out that Pax and Felix whiteboard do not support HttContext sharing over bundles. As a result the relation is one to one. The HttpContext can be shared based on whiteboard and a contextId property, but it is limited to one ResourceProvder serving the resources, again putting complex work on the developer. The HttpContextServiceFactory constructs (nad owns the instance/class/classloader) of the HttpContext implementation but registers it under the callers BundleContext. This is a serious design smell. This mechanism does not provide any solution for handling security. The only thing a developer can do is creating his own HttpContext and having to do all the work himself (inluding jsp). Proposes solution: The whole design sould be converted to whiteboard. This will be required to properly support dispatcher support anyway. The factory is removed and no direct resource registration with HttpService is allowed. The factory is replace with HttpContextManager that constructs and registers HttpContext instances as required based on Servlet/Filter, ResourceProvider and SecurityHandler (new interface) service registrations that specify a contextId service property (conform Felix whiteboard). Each service instance of HttpContext will itself track ResourceProvider and Securityhandler services for its own contextId and delegates the respective .This appraoch will work with our own dispatcher implementation that does not connstrict HttpContext registration to a specific bundle like PAX & Felix do. Just like JspSupport we introduce ResourceSupport that registers ResourceServlets whiteboard style voiding the need for direct calls to HttpService. Note that we should have a close look at both strategies as they now are by convention based on bundle root. Potential security issue and probably in need of declarative options! So it would look like this.. <ApplicationBundles> <JspSupportBundle> <ResourceSupportBundle> <HttpContextBundle> |----------------| |----------------| |----------------| |----------------| |ResourceProvider| |JspServlet | |ResourceServlet | |HttpContext | |----------------| |----------------| |----------------| |----------------| |contextId=XXX | |contextId=XXX | |contextId=XXX | |contextId=XXX | |----------------| |----------------| |----------------| |----------------| |----------------| |SecurityHandler | |----------------| |contextId=XXX | |----------------| |----------------| |Servlet | |----------------| |contextId=XXX | |----------------| |----------------| |Filter | |----------------| |contextId=XXX | |----------------| In addition we considered the possibility that a developer still wants to create his own HttpContext and handling everything himself. This could be supported by inntroducing an optional contextSvc servcice property. In this case the HttpContextManager will not create the instance, but just add it to the registry based on availibility. So it would look like this.. <ApplicationBundles> <JspSupportBundle> <ResourceSupportBundle> <HttpContextBundle> |----------------| |Servlet | |----------------| |contextSvc=XXZ | |----------------| |----------------| |HttpContex | |----------------| |contextSvc=XXZ | |----------------| Open issues: At present we consider that all business components to be tenant aware. Therefore a particalar servlet (either one or more instances) will be registered as a service for each tenant. Should the same apply to HttpContext or should this be a choice. I can imaging for example security to be crosscutting for all tenants in one use case and tenant speicic in another..? Same question can be extended to ResourceProviders/SecurityHandlers.

