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.

Reply via email to