abdera-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ugo Cei <ugo....@gmail.com>
Subject Re: Advice on implementing an APP server
Date Wed, 21 Feb 2007 10:47:07 GMT

On Feb 20, 2007, at 3:26 PM, Adam Constabaris wrote:

> While I'm on (2) (and this is nearer to my immediate concerns, but  
> seems like a ripe subject for documentation): suppose my APP server  
> is part of an existing application that uses Spring with JPA/ 
> Hibernate/JDO/iBatis for data access (or just that I really like  
> Spring IoC and I want to use it behind my new APP server).  I've  
> got this juicy set of services just sitting there, already  
> initialized, and now I need to instantiate a ProviderManager and  
> give it access to those things.  I can't use Spring to inject those  
> services into the ProviderManager instance, because as long as I'm  
> using the stock AbderaServlet, creation of the protocol's factory  
> objects is controlled by the Abdera framework.  Since there doesn't  
> seem to be a way to access the servlet context (where a reference  
> to the Spring context can be held) through the framework classes,  
> it looks like the cleanest approach is to subclass AbderaServlet,  
> which can inject the Spring-managed dependencies into the Abdera  
> factory classes.  Mutatis mutandis if I'm working with EJB3/ 
> Servlets 2.5 and I want to inject container-managed JPA  
> EntityManagers into my Abdera-based classes.

I can tell you what I'm doing in a situation like yours. I'm not sure  
it makes perfectly sense, as it's mostly an experiment, but it might  
be useful to you.

First of all, I'm not extending AbderaServlet, but HttpServlet  
instead, overriding the service() method as follows:

     protected void service(
             HttpServletRequest request,
             HttpServletResponse response)
     throws ServletException, IOException {
         ServiceContext context = (ServiceContext) appCtx.getBean 
("serviceContext");
         RequestHandlerManager manager =  
context.getRequestHandlerManager();
         RequestHandler handler = manager.getRequestHandler();
         try {
             handler.process(context, request, response);
         } catch (Throwable t) {
             logger.error("Error servicing request", t);
             response.setContentType("text/plain");
             PrintWriter out = response.getWriter();
             out.println(t);
             t.printStackTrace(out);
             response.setStatus 
(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
         } finally {
             manager.release(handler);
         }
     }

The appCtx variable is set in the servlet's init method using one of  
the usual Spring approaches:

         ServletContext context = config.getServletContext();
          appCtx =  
WebApplicationContextUtils.getRequiredWebApplicationContext(context);

Then we have a couple beans configured in the application context:

   <bean name="abdera" class="org.apache.abdera.Abdera"/>

   <bean name="serviceContext"  
class="com.sourcesense.restore.server.SpringBasedServiceContext">
     <property name="abdera" ref="abdera"/>
     <property name="providerManager" ref="providerManager"/>
     <property name="requestHandlerManager">
       <bean  
class="org.apache.abdera.protocol.server.servlet.DefaultRequestHandlerMa 
nager"/>
     </property>
     <property name="subjectResolver">
       <bean  
class="org.apache.abdera.protocol.server.util.SimpleSubjectResolver"/>
     </property>
     <property name="targetResolver" ref="resolver"/>
   </bean>

   <bean name="providerManager"  
class="com.sourcesense.restore.server.provider.SpringProviderManager">
     <property name="provider" ref="provider"/>
   </bean>

I am attaching the source for SpringBasedServiceContext and  
SpringProviderManager.

All this is very generic and can be reused in any application. You  
have to write the application-specific parts of the code by providing  
the "resolver" and "provider" bean implementation that implement  
org.apache.abdera.protocol.server.provider.TargetResolver and  
org.apache.abdera.protocol.server.provider.Provider, respectively.

Inside your Provider-implementing class you can get ahold of the  
Abdera object like this:

     public ResponseContext getService(RequestContext request,  
boolean full) {
         Abdera abdera = request.getServiceContext().getAbdera();
        ....
     }

I am planning to release all this code as a whole project, including  
some samples, but I have to get clearance for some IP issues first.  
For the time being, I hope you can use what I described here.

	Ugo


-- 
Ugo Cei
Blog: http://agylen.com/
Open Source Zone: http://oszone.org/
Evil or Not?: http://evilornot.info/
Company: http://www.sourcesense.com/


Mime
View raw message