| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. The ASF licenses this file to You |
| under the Apache License, Version 2.0 (the "License"); you may not |
| use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. For additional information regarding |
| copyright in this work, please see the NOTICE file in the top level |
| directory of this distribution. --> |
| <?xml version="1.0" encoding="UTF-8"?> |
| <!DOCTYPE html |
| PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml"> |
| <head> |
| <title>Apache Abdera</title> |
| <meta name="generator" content="DocBook XSL Stylesheets V1.70.1"/> |
| </head> |
| <body> |
| <!-- Header --> |
| <div id="banner"> |
| <h1><a href="http://incubator.apache.org/abdera">Apache Abdera</a></h1> |
| <p>Version 0.4.0-incubating-SNAPSHOT</p> |
| <hr/> |
| </div> |
| <div id="divider"></div> |
| |
| <h1>Implementing A Server</h1> |
| |
| <div class="article" lang="en"> |
| <div class="titlepage"> |
| <div><div class="author"> |
| <h3 class="author">Contributed by: <span class="firstname">Adam</span> <span class="surname">Constabaris</span></h3> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#intro">Introduction</a></span></dt><dt><span class="section"><a href="#providers">Implementing <code class="classname">Provider</code></a></span></dt><dt><span class="section"><a href="#app_assembly">Putting it all together</a></span></dt></dl></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="intro"/>Introduction</h2></div></div></div><p>The framework for implementing an APP server in Abdera is, as shipped, incomplete, but |
| armed with a knowledge of how APP works, you shouldn't have too much trouble enabling |
| APP access to an (appropriate!) domain model. In order to effectively use the classes in |
| the framework, you'll have to know how to configure them and what you need to implement |
| yourself. The first part of the document describes (loosely) how Abdera is configured, |
| while the second part concerns notes about implementing some of the more important |
| classes. I assume throughout that you are familiar with the Atom format, APP basics, and |
| Abdera's general model for representing the Atom format. </p><p> Abdera is designed to use a controller servlet, and ships with a basic implementation |
| that is be suitable for a range of situations. Changing your Abdera server configuration |
| is largely achieved by setting properties of the form |
| <code class="literal">some.abdera.framework.Interface=my.domain.abdera.InterfaceImplementation</code>; |
| that is, the property's name is the fully qualified name of the interface whose |
| implementation you want to specify, and the value is the fully-qualified name of a class |
| that implements that interface. Swapping out Abdera's default parser factory for a |
| SAX-based one, for example, would be done by setting |
| <span class="property">org.apache.abdera.parser.ParserFactory</span> to (say) |
| <span class="property">net.my.domain.MyParserFactory</span>. </p><p> Properties can be specified in a number of places; first, most of the crucial bits of |
| core Abdera are specified in <code class="classname">org.apache.abdera.util.Constants</code>. |
| You can also use the Java standard <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider" target="_top">service provider</a> mechanism, or a file named |
| <code class="filename">abdera.properties</code> on the classpath (generally, values are looked up |
| in this order, with later values overriding ones set by earlier mechanisms). While |
| Abdera core ships with settings that allow you to parse or create feed documents without |
| any special configuration, server implementations are more variable and so require more |
| work. </p><p>As you might expect, this form of configuration makes heavy use of reflection, and |
| default or well-known constructors. In general, if you don't need to supply a lot of |
| helper classes or are happy using (e.g) JNDI lookup mechanisms to look up such things as |
| database connections, you can use these mechanisms without too much fuss. It's also not |
| much more work to use a dependency injection framework (such as Spring) for your server |
| configuration. </p><p> The interfaces you need to implement in order to create an APP server are listed in |
| <code class="classname">org.apache.abdera.protocol.server.util.ServerConstants</code>: </p><div class="variablelist"><dl><dt><span class="term"> |
| |
| <code class="classname">org.apache.abdera.protocol.server.servlet.RequestHandlerManager</code> |
| </span></dt><dd><p>Factory for objects that control the request processing.</p></dd><dt><span class="term"> |
| <code class="classname">org.apache.abdera.protocol.server.auth.SubjectResolver</code> |
| </span></dt><dd><p>Factory for objects that determine the identity of calling |
| clients.</p></dd><dt><span class="term"> |
| <code class="classname">org.apache.abdera.protocol.server.provider.TargetResolver</code> |
| </span></dt><dd><p>Factory for objects that determine the type of APP entity involved |
| in the request (e.g. entry, collection, media, service, categories)</p></dd><dt><span class="term"> |
| |
| <code class="classname">org.apache.abdera.protocol.server.ServiceContext</code> |
| </span></dt><dd><p>Controller: coordinates all of the other factory classes.</p></dd><dt><span class="term"> |
| <code class="classname">org.apache.abdera.protocol.server.provider.ProviderManager</code> |
| </span></dt><dd><p>Factory for <code class="classname">Provider</code> implementations that |
| implement the CRUD operations of the APP server.</p></dd></dl></div><p> |
| </p><p> The <code class="classname">org.apache.abdera.protocol.server.provider.Provider</code> |
| |
| interface defines all of the CRUD operations involved in the Atom protocol: this is |
| where you put the code that gets entries, collections, service documents,and handles |
| updates and deletions; most of the rest of these classes are involved in making sure an |
| HTTP request is routed to the right method on the <code class="classname">Provider</code>. Since |
| the <code class="classname">ProviderManager</code> class is responsible for instantiating and |
| configuring your <code class="classname">Provider</code> objects, it has an important role to |
| play. Concrete default implementations for most of the other interfaces are provided, |
| but you will have to provide implementations for both |
| <code class="classname">ProviderManager</code> and <code class="classname">Provider</code>. </p><p> An absolutely minimal APP server will also have to configure a target resolver, i.e. provide |
| a way to determine which kind of APP entity is being operated on (i.e. it answers questions of |
| the form "is this a request for a service document?"). In all likelihood, a subclass of |
| <code class="classname">org.apache.abdera.protocol.server.util.RegexTargetResolver</code> |
| |
| will suffice here, since it maps request URIs that match a particular regular expression |
| to entity types. Your subclass can supply the actual mapping that you're going to use |
| (see <code class="classname">SimpleTargetResolver</code> in the server example). Additionally, since the |
| <code class="classname">ServiceContext</code> is responsible for getting references to all these other |
| classes and configuring them (most importantly the <code class="classname">ProviderManager</code>), you'll |
| probably want to subclass it as well. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="providers"/>Implementing <code class="classname">Provider</code></h2></div></div></div><p>While the specifics are going to be largely determined by the type of information your |
| server is processing and how it's stored (e.g. on a file system vs. rows in a database), |
| there are a few things to look out for that apply to any <code class="classname">Provider</code> |
| implementation. One thing you'll definitely need is need a system for turning objects in |
| your domain model into Abdera's model objects, and vice-versa. This part has to be left |
| as an exercise for the reader. </p><p>Most of the methods in the <span class="interface">Provider</span> interface are fairly well |
| described by their names: <code class="methodname">getEntry</code>, for example, is called when |
| the client has called <code class="literal">GET</code> on an entry URI. One exception here is the |
| <code class="methodname">getInfo</code> method, which serves mainly to enable support for |
| HTTP's <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3" target="_top">conditional GET</a> [ <a href="http://fishbowl.pastiche.org/2002/10/21/http_conditional_get_for_rss_hackers" target="_top">see also</a> ]. </p><p> You'll notice that the various <code class="methodname">getXXX</code> methods return a |
| <code class="classname">ResponseInfo</code> object, which encompasses the HTTP response, |
| including the headers and response body. In addition to the |
| <code class="classname">RequestContext</code> argument, these methods also accept a |
| <code class="literal">boolean</code> argument that determines whether the method is evaluating |
| the request for cacheability<sup>[<a id="d0e180" href="#ftn.d0e180">1</a>]</sup> or whether it should actually generate a response body. Let's refer to the |
| first mode (where the boolean parameter is <code class="literal">false</code>) as "header mode" |
| and the second as "full response mode". When the method is called in header mode, it |
| <span class="emphasis"><em>may</em></span> check the <code class="literal">ETag</code> or |
| <code class="literal">If-Modified-Since</code> HTTP headers submitted by the APP client |
| against the entry's current tag or modification time. </p><p>So, if you're implementing conditional GET in your <code class="classname">Provider</code>, |
| the <code class="methodname">getInfo</code> method can delegate to the appropriate |
| <code class="methodname">getXXX</code> method in header mode. Even if your provider |
| <span class="emphasis"><em>doesn't</em></span> support conditional GET, you'll probably want to |
| support different header and full response modes, to avoid having to generate a |
| potentially "expensive" document twice. A relatively straightforward way to do this is |
| to have your methods return an <code class="classname">EmptyResponseContext</code> with a status |
| code of 200 (or 404, if the user's requested an entry that doesn't exist) when they're |
| called in header mode. The default request processing pipeline ensures that the method |
| will be called again in full response mode.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="app_assembly"/>Putting it all together</h2></div></div></div><p>The default <code class="classname">AbderaServlet</code> class can be used as your servlet controller, but |
| it is somewhat limited in how much "help" it can provide by way of making servlet or EJB container resources such as |
| database connection pools available to your protocol implementation. <code class="classname">AbderaServlet</code> |
| |
| uses the property-resolution mechanisms described above<sup>[<a id="d0e224" href="#ftn.d0e224">2</a>]</sup>. The basic |
| steps it uses to process a request are: |
| </p><div class="procedure"><ol type="1"><li><p>Obtain a reference to a <code class="classname">ServiceContext</code> (via reflection).</p></li><li><p>Use the service context to get a reference to a <code class="classname">RequestHandlerManager</code>.</p></li><li><p>Use the request handler manager to obtain a <code class="classname">RequestHandler</code>.</p></li><li><p>Call <code class="methodname">process()</code> on the request handler.</p></li></ol></div><p> |
| |
| If your <code class="classname">ServiceContext</code> implementation can get references to |
| appropriately configured target resolvers and provider managers, then all you need to do |
| is map the AbderaServlet to the desired URI and set the <span class="property">org.apache.abdera.protocol.server.ServiceContext</span> |
| property to the name of your service context implementation. |
| </p><p> |
| If you require greater control over how the <code class="classname">ServiceContext</code> is instantiated or |
| configured, you should create your own servlet whose <code class="methodname">service</code> method executes |
| this basic process. |
| </p></div><div class="footnotes"><br/><hr width="100" align="left"/><div class="footnote"><p><sup>[<a id="ftn.d0e180" href="#d0e180">1</a>] </sup>They can also check that certain preconditions are satisfied, |
| e.g. the "lost update" mechanism for a PUT (update) request, which checks |
| whether the ETag supplied by the client matches the current ETag for the |
| associated entry, but I'll leave that part out.</p></div><div class="footnote"><p><sup>[<a id="ftn.d0e224" href="#d0e224">2</a>] </sup>With one twist: it also lets you specify your |
| implementation classes via the servlet's initialization parameters.</p></div></div></div></body></html> |