cocoon-docs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From da...@cocoon.zones.apache.org
Subject [DAISY] Updated: The OSGi fundament
Date Mon, 22 May 2006 18:09:09 GMT
A document has been updated:

http://cocoon.zones.apache.org/daisy/documentation/1151.html

Document ID: 1151
Branch: main
Language: default
Name: The OSGi fundament (unchanged)
Document Type: Cocoon Document (unchanged)
Updated on: 5/22/06 6:08:45 PM
Updated by: Reinhard Pötz

A new version has been created, state: draft

Parts
=====
Content
-------
This part has been updated.
Mime type: text/xml (unchanged)
File name:  (unchanged)
Size: 12267 bytes (previous version: 94 bytes)
Content diff:
    <html>
    <body>
    
+++ <h1>Big picture</h1>
+++ 
+++ <p>We have a number of different parts:</p>
+++ 
+++ <ul>
+++ <li>A <strong>dispatcher</strong> (ServletRegistrationActivator) - where
the
+++ blocks are mounted with their respective URI prefixes.</li>
+++ <li><strong>Inter block component management</strong> - a block can
make its
+++ components available to other blocks, and use components from other blocks.
+++ </li>
+++ <li><strong>Component manager bridges</strong> (OSGiSpringBridge) -
the
+++ components within a block can be setup by our Spring container or maybe by some
+++ other kind of container.</li>
+++ <li><strong>Inter block communication and polymorphism</strong> - a
sitemap, and
+++ more generally a servlet, can call servlets in other blocks. And there is also
+++ inheritance so that one sitemap (or servlet) can extend another one.</li>
+++ <li><strong>Dynamic deployment and configuration </strong>- the blocks
can be
+++ installed, updated, reconfigured and removed dynamically while the rest of the
+++ framework is executing.</li>
+++ </ul>
+++ 
    <p><img src="daisy:1160"/></p>
    
--- <p>UML 2 component diagram</p>
+++ <p class="warn">Not everything implemented yet!</p>
    
+++ <p>First a little bit about Declarative Services (DS), that is used everywhere
+++ in the design and replaces block.xml among other things in the current design.
+++ </p>
+++ 
+++ <h1>Declarative Services</h1>
+++ 
+++ <p>The declarative services simplify service (component) handling in OSGi by
+++ making it possible to declare services and their dependencies in an XML file
+++ (before service management wasn't configuration file based in OSGi). <br/>
+++ The DS supports setter injection. Compared to Spring it is rather small and
+++ primitive. The cool thing about it is that it support dynamic dependencies. A
+++ dynamic dependency can have both a setter and an un-setter. <br/>
+++ The framework also takes care of stopping and starting non-dynamic components
+++ when their dependencies comes and goes.<br/>
+++ The DS can be used together with a configuration service that can override the
+++ default configurations in the DS XML file. The configuration service can take
+++ part of the responsibility that the wiring file and deployer takes in the
+++ current architecture. <br/>
+++ There is not much documentation for the DS yet, so the main references are the
+++ specification [1] and the documentation of the service binder [2] that was a
+++ predecessor of DS.</p>
+++ 
+++ <h1>The dispatcher</h1>
+++ 
+++ <p>The role of the dispatcher (ServletRegistrationActivator) is that the blocks
+++ (servlets) are mounted in it based together with their URI prefixes. The
+++ dispatcher then call the blocks based on the incoming URIs. This is already
+++ handled by the OSGi HTTP service which provides a service that a servlet can
+++ lookup and register it self in. <br/>
+++ A HTTP service implementation normally contains a HTTP server. But an
+++ alternative for embedding OSGi managed servlets in a servlet container is to use
+++ a HTTP service that acts as a bridge to the embedding servlet container. [3]
+++ <br/>
+++ It is also inconvenient to require the servlets to lookup the HTTP service. It
+++ is better to use the whiteboard pattern [4], and just register the servlets as
+++ services and have a component that reacts on the appearance and disappearance of
+++ servlet services, and register and unregister them in the HTTP service
+++ respectively.</p>
+++ 
+++ <p>Using DS a declaration (which is referred to by the Service-Component
+++ property in the manifest file) for a "whiteboard" adapter can look like [5]:
+++ </p>
+++ 
+++ <pre>  &lt;scr:component name="cocoon.activator"&gt;
+++     &lt;scr:implementation class="org.apache.cocoon.blocks.osgi.Activator"/&gt;
+++     &lt;scr:reference name="LOG"
+++                    interface="org.osgi.service.log.LogService"
+++                    bind="setLog"/&gt;
+++     &lt;scr:reference name="HTTP"
+++                    interface="org.osgi.service.http.HttpService"
+++                    bind="setHttpService"/&gt;
+++     &lt;scr:reference name="Servlet"
+++                    interface="javax.servlet.Servlet"
+++                    cardinality="0..n"
+++                    policy="dynamic"
+++                    bind="setServlet"
+++                    unbind="unsetServlet"/&gt;
+++   &lt;/scr:component&gt;
+++ </pre>
+++ 
+++ <p>which activates the class <tt>o.a.c.blocks.osgi.Activator</tt> [6]
by calling
+++ its  <tt>void activate(ComponentContext)</tt>"method if there is one. We
can
+++ also see that the declaration refers to other services. It will not be activated
+++ until all its references are fulfilled. In this case it require a log service
+++ and an HTTP service to be present, and will insert these into the Activator
+++ instance by using its setLog and setHttpService methods.</p>
+++ 
+++ <p>The servlet reference is more interesting, it is dynamic an it has
+++ cardinality 0..n. This means that the activator can be connected to many
+++ servlets and that they can come and go dynamically. Each time a servlet service
+++ appears the setServlet method is called with it and each time one disappear the
+++ unsetServlet method is called.</p>
+++ 
+++ <p>The name attribute for the references are used for allowing service manager
+++ style lookup using the name, within the component. The service manager can be
+++ get through the ComponentContext.</p>
+++ 
+++ <h1>A Servlet Service</h1>
+++ 
+++ <p>A bundle that provides a servlet, can register it as a service with a
+++ declaration like [5]:</p>
+++ 
+++ <pre>  &lt;scr:component name="cocoon.servlet3"&gt;
+++     &lt;scr:implementation class="org.apache.cocoon.blocks.osgi.TestServlet"/&gt;
+++     &lt;scr:service&gt;
+++       &lt;scr:provide interface="javax.servlet.Servlet"/&gt;
+++     &lt;/scr:service&gt;
+++     &lt;scr:property name="path" value="/test3"/&gt;
+++   &lt;/scr:component&gt;
+++ </pre>
+++ 
+++ <p>compared to the whiteboard adapter we can see some new things, here we
+++ provide a service to the framework and it can be refered to by the name
+++ "cocoon.servlet3" (we should use a better naming scheme, I just adapted some
+++ examples from the specification while implementing the above).</p>
+++ 
+++ <p>The declaration also contains a property: <tt>path=/test3</tt>, that
is
+++ looked up by the whiteboard adapter and used for mounting the servlet at that
+++ URI context.</p>
+++ 
+++ <p>This far we can see that by using what OSGi implementations already contain
+++ and some minimal glue code [6], we get the possiblity to dynamically register
+++ (and unregister) servlets within a webapp.</p>
+++ 
+++ <p>In the next step we will see how these servlets can share (dynamic)
+++ components.</p>
+++ 
+++ <h1>Component Management</h1>
+++ 
+++ <p>Actually we already have inter block component management from OSGi. A bundle
+++ (block) can provide components by declaring them as services and it can depend
+++ on other components, possibly from other bundles by declaring them as
+++ references.</p>
+++ 
+++ <p>More specifically, for a servlet to depend on some components, we can add a
+++ number of set (and unset if we want dynamism) methods to it, and add the
+++ corresponding references in its declaration.</p>
+++ 
+++ <p>So, by just using OSGi, we get much of what the block architecture is
+++ intended for: dynamic component handling, packaging of servlets (sitemaps),
+++ sharing of components between blocks.</p>
+++ 
+++ <h1>Component Manager Bridges</h1>
+++ 
+++ <p>While DS is neat, it is not as flexible and powerful as Spring and we still
+++ have our legacy of Avalon components to take care of.</p>
+++ 
+++ <p>To create a bridge between OSGi services and Spring or Avalon component
+++ management we need two kind of adapters:</p>
+++ 
+++ <ul>
+++ <li>An OSGi service to ServiceManager (or BeanFactory) adapter. This adapter
+++ just implement ServiceManager (or BeanFactory) and lookup the components OSGi
+++ services. It could be registered as an OSGi service it self and refered to by
+++ other components that needs a ServiceManager. We can even get dynamism by
+++ creating the adapter with DS and explicitly list the services that it should be
+++ able to provide, as references.</li>
+++ <li>A Spring component manager to OSGi services adapter. This adapter register
+++ all the components that is created by the Spring container as services. By
+++ letting the Spring container have a OSGi service to BeanFactory adapter as
+++ parent component manager, the Spring component manager can use components from
+++ other blocks as well, while creating new components.</li>
+++ </ul>
+++ 
+++ <p>We have already implemented this kind of bridge for ECM++ [7]. Now we need to
+++ implement it for the new Spring based container.</p>
+++ 
+++ <h1>Inter Block Communication</h1>
+++ 
+++ <p>The servlets (sitemaps) in the different blocks need to be able to call each
+++ other. Also it simplifies reuse of blocks if one block can extend another one
+++ (or rather that a servlets in one block can extend a servlet in another one).
+++ This is achieved with the block protocol.</p>
+++ 
+++ <p>One way of thinking about the inter block communication is to consider the
+++ servlet in the block to be embedded in an own container where the the servlets
+++ of the other blocks are available through the servlet context. This is the way I
+++ have implemented it, so other servlets can be called through the
+++ getNamedDispatcher method of the servlet context, with the block name as
+++ argument.</p>
+++ 
+++ <p>The implementation of calls to super blocks and polymorphism requires the use
+++ of a call stack, see [8] for details.</p>
+++ 
+++ <p>Block properties are accessed as servlet config (and context) init
+++ parameters.</p>
+++ 
+++ <p>In the OSGi implementation there is a BlockServlet that sets up the the
+++ communication with other blocks and creates the context that the servlet of the
+++ own block is executed within. A declaration of a BlockServlet might look like:
+++ </p>
+++ 
+++ <pre>  &lt;scr:component name="cocoon.blockServlet2"&gt;
+++     &lt;scr:implementation class="org.apache.cocoon.blocks.osgi.BlockServlet"/&gt;
+++     &lt;scr:service&gt;
+++       &lt;scr:provide interface="javax.servlet.Servlet"/&gt;
+++     &lt;/scr:service&gt;
+++     &lt;scr:property name="path" value="/test2"/&gt;
+++     &lt;scr:property name="attr" value="bar"/&gt;
+++     &lt;scr:reference name="blockServlet"
+++                    interface="javax.servlet.Servlet"
+++                    target="(component.name=cocoon.servlet2)"/&gt;
+++     &lt;scr:reference name="block1"
+++                    interface="javax.servlet.Servlet"
+++                    target="(component.name=cocoon.blockServlet1)"/&gt;
+++   &lt;/scr:component&gt;
+++ </pre>
+++ 
+++ <p>Here we can see that we provide a service with the identifier
+++ "cocoon.blockServlet2" that is implemented by the mentioned BlockServlet and
+++ implements Servlet, it is mounted on the path "/test2". So the "whiteboard" part
+++ of the dispatcher described above, will take care of installing this block
+++ servlet in the HttpService of the framework.</p>
+++ 
+++ <p>The servlet reference with the special name "blockServlet" (should find a
+++ less confusing name) refer to the servlet that is embedded by the BlockServlet.
+++ The embeded servlet could e.g. be a sitemap servlet, and it could get the
+++ components it needs through the mechanism described in the sections about
+++ component management above.</p>
+++ 
+++ <p>The "target" attribute in a reference can contain constraints on what service
+++ that is refered to. The constraint "(component.name=cocoon.servlet2)" means that
+++ we want the particular servlet that is registered under the name
+++ "cocoon.servlet2". The constraint lanuage is the same as is used in LDAP, and it
+++ is possible to  create rather complex constraints if needed.</p>
+++ 
+++ <p>We can also see that there is a reference to a block servlet with the
+++ identifier "cocoon.blockServlet1", it will be made available through the
+++  servlet context for "cocoon.servlet2" with the getNamedDispatcher method  using
+++ the name "block1".</p>
+++ 
+++ <p>All the properties (path and attr) are made available as init parameters in
+++ the servlet context for "cocoon.servlet2".</p>
+++ 
+++ <p>As we can see, the above DS configuration of a block servlet take care of
+++ most of what is configured in block.xml in the current block architecture.</p>
+++ 
+++ <h1>The Block Protocol</h1>
+++ 
+++ <p>OSGi have an URL service that make it possible to dynamically add protocols
+++ that are available through java.net.URL, much like the Excalibur sources. I have
+++ reimplemented the block source as an URLConnection that is registered as a
+++ protocol and can be used like in [9] (still buggy code).</p>
+++ 
    </body>
    </html>


Fields
======
no changes

Links
=====
no changes

Custom Fields
=============
no changes

Collections
===========
no changes

Mime
View raw message