Return-Path: Delivered-To: apmail-cocoon-docs-archive@www.apache.org Received: (qmail 11976 invoked from network); 22 May 2006 18:09:44 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 22 May 2006 18:09:44 -0000 Received: (qmail 11811 invoked by uid 500); 22 May 2006 18:09:43 -0000 Delivered-To: apmail-cocoon-docs-archive@cocoon.apache.org Received: (qmail 11779 invoked by uid 500); 22 May 2006 18:09:43 -0000 Mailing-List: contact docs-help@cocoon.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: docs@cocoon.apache.org List-Id: Delivered-To: mailing list docs@cocoon.apache.org Received: (qmail 11767 invoked by uid 99); 22 May 2006 18:09:43 -0000 X-ASF-Spam-Status: No, hits=0.6 required=10.0 tests=NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [207.7.158.203] (HELO cocoon.zones.apache.org) (207.7.158.203) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 May 2006 11:09:42 -0700 Message-ID: <18828841.1148321349217.JavaMail.daisy@cocoon.zones.apache.org> Date: Mon, 22 May 2006 18:09:09 +0000 (GMT+00:00) From: daisy@cocoon.zones.apache.org To: docs@cocoon.apache.org Subject: [DAISY] Updated: The OSGi fundament Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N 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=C3=B6tz A new version has been created, state: draft Parts =3D=3D=3D=3D=3D Content ------- This part has been updated. Mime type: text/xml (unchanged) File name: (unchanged) Size: 12267 bytes (previous version: 94 bytes) Content diff: =20 +++

Big picture

+++=20 +++

We have a number of different parts:

+++=20 +++
    +++
  • A dispatcher (ServletRegistrationActivator) - wher= e the +++ blocks are mounted with their respective URI prefixes.
  • +++
  • Inter block component management - a block can mak= e its +++ components available to other blocks, and use components from other blo= cks. +++
  • +++
  • Component manager bridges (OSGiSpringBridge) - the +++ components within a block can be setup by our Spring container or maybe= by some +++ other kind of container.
  • +++
  • Inter block communication and polymorphism - a sit= emap, 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. +++
  • Dynamic deployment and configuration - the blocks = can be +++ installed, updated, reconfigured and removed dynamically while the rest= of the +++ framework is executing.
  • +++
+++=20

=20 ---

UML 2 component diagram

+++

Not everything implemented yet!

=20 +++

First a little bit about Declarative Services (DS), that is used eve= rywhere +++ in the design and replaces block.xml among other things in the current = design. +++

+++=20 +++

Declarative Services

+++=20 +++

The declarative services simplify service (component) handling in OS= Gi by +++ making it possible to declare services and their dependencies in an XML= file +++ (before service management wasn't configuration file based in OSGi). +++ The DS supports setter injection. Compared to Spring it is rather small= and +++ primitive. The cool thing about it is that it support dynamic dependenc= ies. A +++ dynamic dependency can have both a setter and an un-setter.
+++ The framework also takes care of stopping and starting non-dynamic comp= onents +++ when their dependencies comes and goes.
+++ The DS can be used together with a configuration service that can overr= ide the +++ default configurations in the DS XML file. The configuration service ca= n take +++ part of the responsibility that the wiring file and deployer takes in t= he +++ current architecture.
+++ 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.

+++=20 +++

The dispatcher

+++=20 +++

The role of the dispatcher (ServletRegistrationActivator) is that th= e blocks +++ (servlets) are mounted in it based together with their URI prefixes. Th= e +++ dispatcher then call the blocks based on the incoming URIs. This is alr= eady +++ handled by the OSGi HTTP service which provides a service that a servle= t can +++ lookup and register it self in.
+++ 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] +++
+++ It is also inconvenient to require the servlets to lookup the HTTP serv= ice. It +++ is better to use the whiteboard pattern [4], and just register the serv= lets as +++ services and have a component that reacts on the appearance and disappe= arance of +++ servlet services, and register and unregister them in the HTTP service +++ respectively.

+++=20 +++

Using DS a declaration (which is referred to by the Service-Componen= t +++ property in the manifest file) for a "whiteboard" adapter can look like= [5]: +++

+++=20 +++
=C2=A0 <scr:component name=3D"cocoon.activator">
+++ =C2=A0=C2=A0=C2=A0 <scr:implementation class=3D"org.apache.cocoon.bl=
ocks.osgi.Activator"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:reference name=3D"LOG"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 interface=3D"org.osgi.service.log.L=
ogService"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bind=3D"setLog"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:reference name=3D"HTTP"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 interface=3D"org.osgi.service.http.=
HttpService"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bind=3D"setHttpService"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:reference name=3D"Servlet"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 interface=3D"javax.servlet.Servlet"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 cardinality=3D"0..n"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 policy=3D"dynamic"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bind=3D"setServlet"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unbind=3D"unsetServlet"/>
+++ =C2=A0 </scr:component>
+++ 
+++=20 +++

which activates the class o.a.c.blocks.osgi.Activator [6] b= y calling +++ its=C2=A0 void activate(ComponentContext)"method if there is o= ne. 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 s= ervice +++ and an HTTP service to be present, and will insert these into the Activ= ator +++ instance by using its setLog and setHttpService methods.

+++=20 +++

The servlet reference is more interesting, it is dynamic an it has +++ cardinality 0..n. This means that the activator can be connected to man= y +++ 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 disap= pear the +++ unsetServlet method is called.

+++=20 +++

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.

+++=20 +++

A Servlet Service

+++=20 +++

A bundle that provides a servlet, can register it as a service with = a +++ declaration like [5]:

+++=20 +++
=C2=A0 <scr:component name=3D"cocoon.servlet3">
+++     <scr:implementation class=3D"org.apache.cocoon.blocks.osgi.TestS=
ervlet"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:service>
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <scr:provide interface=3D"javax.servl=
et.Servlet"/>
+++ =C2=A0=C2=A0=C2=A0 </scr:service>
+++ =C2=A0=C2=A0=C2=A0 <scr:property name=3D"path" value=3D"/test3"/>
+++ =C2=A0 </scr:component>
+++ 
+++=20 +++

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).

+++=20 +++

The declaration also contains a property: path=3D/test3, th= at is +++ looked up by the whiteboard adapter and used for mounting the servlet a= t that +++ URI context.

+++=20 +++

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 re= gister +++ (and unregister) servlets within a webapp.

+++=20 +++

In the next step we will see how these servlets can share (dynamic) +++ components.

+++=20 +++

Component Management

+++=20 +++

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.

+++=20 +++

More specifically, for a servlet to depend on some components, we ca= n add a +++ number of set (and unset if we want dynamism) methods to it, and add th= e +++ corresponding references in its declaration.

+++=20 +++

So, by just using OSGi, we get much of what the block architecture i= s +++ intended for: dynamic component handling, packaging of servlets (sitema= ps), +++ sharing of components between blocks.

+++=20 +++

Component Manager Bridges

+++=20 +++

While DS is neat, it is not as flexible and powerful as Spring and w= e still +++ have our legacy of Avalon components to take care of.

+++=20 +++

To create a bridge between OSGi services and Spring or Avalon compon= ent +++ management we need two kind of adapters:

+++=20 +++
    +++
  • An OSGi service to ServiceManager (or BeanFactory) adapter. This ad= apter +++ just implement ServiceManager (or BeanFactory) and lookup the component= s 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 s= hould be +++ able to provide, as references.
  • +++
  • A Spring component manager to OSGi services adapter. This adapter r= egister +++ 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 componen= ts from +++ other blocks as well, while creating new components.
  • +++
+++=20 +++

We have already implemented this kind of bridge for ECM++ [7]. Now w= e need to +++ implement it for the new Spring based container.

+++=20 +++

Inter Block Communication

+++=20 +++

The servlets (sitemaps) in the different blocks need to be able to c= all each +++ other. Also it simplifies reuse of blocks if one block can extend anoth= er one +++ (or rather that a servlets in one block can extend a servlet in another= one). +++ This is achieved with the block protocol.

+++=20 +++

One way of thinking about the inter block communication is to consid= er the +++ servlet in the block to be embedded in an own container where the the s= ervlets +++ 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 a= s +++ argument.

+++=20 +++

The implementation of calls to super blocks and polymorphism require= s the use +++ of a call stack, see [8] for details.

+++=20 +++

Block properties are accessed as servlet config (and context) init +++ parameters.

+++=20 +++

In the OSGi implementation there is a BlockServlet that sets up the = the +++ communication with other blocks and creates the context that the servle= t of the +++ own block is executed within. A declaration of a BlockServlet might loo= k like: +++

+++=20 +++
=C2=A0 <scr:component name=3D"cocoon.blockServlet2">
+++     <scr:implementation class=3D"org.apache.cocoon.blocks.osgi.Block=
Servlet"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:service>
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 <scr:provide interface=3D"javax.servl=
et.Servlet"/>
+++ =C2=A0=C2=A0=C2=A0 </scr:service>
+++ =C2=A0=C2=A0=C2=A0 <scr:property name=3D"path" value=3D"/test2"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:property name=3D"attr" value=3D"bar"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:reference name=3D"blockServlet"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 interface=3D"javax.servlet.Servlet"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 target=3D"(component.name=3Dcocoon.=
servlet2)"/>
+++ =C2=A0=C2=A0=C2=A0 <scr:reference name=3D"block1"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 interface=3D"javax.servlet.Servlet"
+++ =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 target=3D"(component.name=3Dcocoon.=
blockServlet1)"/>
+++ =C2=A0 </scr:component>
+++ 
+++=20 +++

Here we can see that we provide a service with the identifier +++ "cocoon.blockServlet2" that is implemented by the mentioned BlockServle= t and +++ implements Servlet, it is mounted on the path "/test2". So the "whitebo= ard" part +++ of the dispatcher described above, will take care of installing this bl= ock +++ servlet in the HttpService of the framework.

+++=20 +++

The servlet reference with the special name "blockServlet" (should f= ind a +++ less confusing name) refer to the servlet that is embedded by the Block= Servlet. +++ The embeded servlet could e.g. be a sitemap servlet, and it could get t= he +++ components it needs through the mechanism described in the sections abo= ut +++ component management above.

+++=20 +++

The "target" attribute in a reference can contain constraints on wha= t service +++ that is refered to. The constraint "(component.name=3Dcocoon.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 LDA= P, and it +++ is possible to =C2=A0create rather complex constraints if needed.

+++=20 +++

We can also see that there is a reference to a block servlet with th= e +++ identifier "cocoon.blockServlet1", it will be made available through th= e +++ =C2=A0servlet context for "cocoon.servlet2" with the getNamedDispatcher= method=C2=A0 using +++ the name "block1".

+++=20 +++

All the properties (path and attr) are made available as init parame= ters in +++ the servlet context for "cocoon.servlet2".

+++=20 +++

As we can see, the above DS configuration of a block servlet take ca= re of +++ most of what is configured in block.xml in the current block architectu= re.

+++=20 +++

The Block Protocol

+++=20 +++

OSGi have an URL service that make it possible to dynamically add pr= otocols +++ that are available through java.net.URL, much like the Excalibur source= s. I have +++ reimplemented the block source as an URLConnection that is registered a= s a +++ protocol and can be used like in [9] (still buggy code).

+++=20 Fields =3D=3D=3D=3D=3D=3D no changes Links =3D=3D=3D=3D=3D no changes Custom Fields =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D no changes Collections =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D no changes