Hi Stefano, Thanks for starting the ball here :) On Sat, Nov 02, 2002 at 01:12:09AM +0100, Stefano Mazzocchi wrote: > > A step back: what are the problems we are trying to solve > --------------------------------------------------------- > <snip/> > Are we really cloning the servlet API? > -------------------------------------- > <snip/> > Anyway, looking at this parallel, Cocoon really lacks a way to make its > applications deployed easily within a 'naked' container that includes > only the basic and default machinery.
Yes, I think we all agree here. > Applying Avalon COP philosophy over again > ----------------------------------------- > <snip/> > Once you start using COP (component oriented programming), it's very > hard to go back (so much so that many abuse it and over-componentize > their systems... even Cocoon itself suffers from this problem on some > parts). :) <snip/> > Improvement #1: component-oriented deployment > --------------------------------------------- > <snip/> > case 2: block-like deployment > > +-----+ +-------+ > | FOP | | Batik | > +-----+ +-------+ > | \ | > | \ | > +---------+ +---------+ > | webapp1 | | webapp2 | > +---------+ +---------+ > > The second case allows: > > - optimization of resources (libraries are not deployed more than needed) > > - separate distributions (different packages can be prepared and > maintained by different groups independently, as long as the service > contracts remain the same) +1, good use case. > Improvement #2: polymorphic behavior > ------------------------------------ > > The above solution already improves on the WAR model, but we can do > better than this. Another use-case scenario: > > In the previous scenario, your web application required PDF > serialization and, in fact, it mixes concerns if it depends *explicitly* > on FOP since, later on, you might want to use another library/service > that implements the same (for example iText or RenderX). > > So, instead of depending on a particular *implementation* of a service > behavior, if we make blocks depending on *behaviors* directly > (considered as service contracts) we can implement polymorphic behavior > of blocks. Similar to virtual-packages in Debian ? eg: exim; provides: mail-transport-agent sendmail; provides: mail-transport-agent mutt: depends: mail-transport-agent Which allows you to install any particular implementation of a virtual-package. <snip/> > case 2: dependency on behavior > > +-----------+ +-----------+ > | +-----+ | | +-------+ | > | | FOP | | | | Batik | | > | +-----+ | | +-------+ | > | FO->PDF | | SVG->PNG | > +-----------+ +-----------+ > | \ | > | \ | > +---------+ +---------+ > | webapp1 | | webapp2 | > +---------+ +---------+ > > Here, the webapp1 requires "fo-pdf" serialization services but it does > not care (nor should!) which implementation of this service is actually > located into the system. > > It is, in fact, the installer's concern to indicate *what* block that > *implements* that behavior should be used in that system at that time. > > Note that this allows several very intersting things: > > 1) versioning: it is possible install several different versions of the > same block and try them out (even at runtime) and roll-back if the > version creates incompatibilities without having to change anything in > the blocks, but only using the block manager (which is the part of > cocoon responsible for deployment and configuration of blocks in the > system). > > 2) polymorphism: I can have different implementations of the same > behavior and I can switch them simply by acting on the block manager, > without having to touch a single configuration line in any block. The > blocks are, in fact, sealed. Does the installer choose based on some policy which implementation will be used, or will it require an admin to choose it at install time ? If its policy based, do you think it's worth having the possibility to recommend a particular implementation due to other concerns outside of functionality like performance ? defects ? etc ? I'm not sure how FOP and iText compare in performance but if your application is really performance critical, and assuming both serializers are feature complete (as far as your report is concerned) being able to 'Recommend' (Debian talk) the faster one might be useful. Similarly if there are 2 blocks that implement the same block interface, but one of them contains a known defect, being able to 'Recommend' the other one might also be desirable, especially if the blocks are hosted from a source the user has no direct influence over. > Improvement #3: block inheritance > --------------------------------- > > The third step is to allow blocks to extends other blocks. > <snip/> > This mainly: > > - reduces block development and maintanance costs because changes and > bugfixes are directly inherited by all the extending blocks, thus > allowing better SoC between the two groups mainaining the different blocks > > - easy customization: blocks can be adapted for personal specific > needs simply with a wrapper around and without the need to repackaging. +1, great. (I agree with Sylvain's comments about the Block API identifying services rather than resources). > +---------------------------+ > | Part 2: technical details | > +---------------------------+ > > Ok. Now that we have described where we want to go, let's describe how. > > Cocoon Blocks > ------------- > > A Cocoon block is a zipped archive, just like JARs and WARs. <snip/> > The main COB descriptor file is found at > > /BLOCK-INF/block.xml > > This file contains markup with a cob-specific namespace and will include > the following information: > > 1) block implementation metadata: > - unique URI identifier [this identifier will also be used as an > address on where to locate the block and how to download it from the > web!] (example: http://mystuff.org/dist/myblock-1.5.34.cob) > - version (1.5.34) > - short name (My Block) > - description > - author > - URI of license (http://mystuff.org/dist/license) > - URI of the distribution location > (http://mystuff/dist/latest/myblock.cob) > - ??? > > 2) role(s): > the URI(s) of the behavioral role(s) this block implements > and exposes [optional] Do you mean the specification of which 'virtual-block's this particular block implements, and/or extra services that are exposed as part of this Blocks API ? <snip/> > Also, the /BLOCK-INF/ directory contains the 'roles' file for Avalon > components: > > /BLOCK-INF/roles.xml After looking at the Merlin/etc oriented way of specifiying Avalon components, I'd be more inclined to use the x-files if possible (we could perhaps retain a roles.xml for ECM style compatibility reasons though). RoleManager just provides the ability to shortcut your configurations (and with the introduction of Fortress specify your component handler), whereas the x-files allow you to do full meta-info analysis of components which I presume would be a necessity in such a distributed system. Merlin style x-files are described at http://jakarta.apache.org/avalon/excalibur/merlin/assembly.html. Essentially for each Avalon Component there is a manifest entry identifying it as so, and a .xinfo & .xprofile file identifying role oriented and instance information of the component. With this approach, components are loaded and validated automatically, and the container can tell you even before a client requests the first component whether the request and use of the component will succeed (as far as dependancies on other components, context entries, component versions, etc, go). > Possible use-case scenario > -------------------------- > > Suppose you have your naked cocoon running in your favorite servlet > container, and you want to deploy myblock.cob. Here is a possible > sequence of actions on an hypotetical web interface on top of Cocoon > (a-la Tomcat Manager) > > 1) upload the myblock.cob to Cocoon > > 2) Cocoon scans /BLOCK-INF/, reads block.xml and finds out the > behaviors this block depends on as well as the block that it extends. > > 3) the block manager connects to the uber "Cocoon Block Librarian" web > service (hosted probably on cocoon.apache.org) and asks for the list of > blocks that exhibit that required behavior. > > 4) the librarian returns a list of those blocks, so the users chooses, > or the manager allows the user to deploy its own block that implements > the required behavior or to reuse those already deployed blocks that > implement the required behaviors. > > 5) Cocoon checks that all dependencies are met, then unpacks and > installs the blocks > > 6) For each block that exposes a sitemap, the deployment manager asks > the deploying user where he/she wants to *mount* that block in the > managed URI space or if he/she wants to keep them internal only (thus > only available to the other blocks, but not mounted on the public URI space) > > 7) for each block that requires installation-time configurations, the > block manager will present the user information on how to configure the > block. > > 8) If no collisions in the URI spaces are found, the blocks are made > available for servicing. Sounds good to me, it would be also nice if the whole process could be automated in some way without manual intervention though. I think this is where my 'Recommends' comment way above comes from. For example, our application servers (16 of them) are restarted daily at 7am and it would be nice if the systems could come up automatically without requiring a deployment admin to answer/manually configure each of the 16 systems at startup/installation time. Perhaps deployment configuration settings/profiles could be given to the deployment manager for automatic block deployment ? (...how many times can I use deployment in the once sentence!) :) > Resource dereferencing > ---------------------- <snip> > The proposed solution is to use block-specific protocols to identify the > dereferenced resources. > > For example, the myblock.cob/sitemap.xmap file could contain a global > matcher which works like this: > > <map:match pattern="**/*.html"> > <map:generate src="{1}.xml"/> > <map:transform src="block:skin:/stylesheets/document2html.xslt"/> > <map:serialize/> > </map:match> > > please note the > > block:skin:/stylesheets/document2html.xslt > > which indicates > > block -> use the block protocol > > skin -> use the 'skin' prefix to lookup the block behavior URI and thus > the block which implements it for this block (the block manager knows > this) > > /stylesheets/document2html.xslt -> it will ask the sitemap of the skin > block to produce that resource. Will the block protocol also be networkable and allow blocks on other hosts to be mounted remotely ? > Dereferencing navigation > ------------------------ <snip/> > For example, things like > > <form action="block:web-service:/post">...</form> > > is trasnformed into > > <form action="/servizio-web/post"/>...</form> +1 > Some design decision taken > -------------------------- > > o) NO BEHAVIOR VALIDATION: > > I thought a lot about it but I think that having 'behavior description > languages' (such as the WSDL-equivalent for blocks) is going to be > terribly complicated, expensive to implement and hard to use and > enforce, even for simple blocks which don't expose a sitemap and are > just repositories for informations. > > For this reason, there is no validation taking place: if a block > implements a particular behavior and exposes it thru its descriptor > file, Cocoon automatically assume it implements the behavior correctly. > > In the future, we might think of adding a behavior description layer to > enforce a little more validation, but I fear the complexity (for > example) of validating stylesheets against a particular required > behavior. > > IMO, only human try/fail and patching will allow interoperability. On a side subject, how about a tool that could generate a skeleton block based on the block interfaces one wants to implement (ie. the block.xml, sitemap.xmap, etc). That would make it a bit nicer for developers as the tool could provide skeletons for what needs to be implemented for that block to correctly implement particular block interfaces. > o) VERSIONING AS PART OF THE BEHAVIOR URI <snip/> > o) CROSS-BLOCK SECURITY <snip/> > o) COCOON MANAGER SECURITY > > The cocoon manager might be a block itself that connects to specific > cocoon internals and provides a web interface for it. So, it can be > removed or disabled when put on production. > > Also, the feature of automatic discovery of blocks thru the 'cocoon > block library' can be turned off or substituted with its own (even the > 'cocoon block library' could be a block, so you could have your own > block library on your system instead of connecting to the apache one). +1, good idea. Perhaps automated block deployment could be done with a particular implementation of the 'automatic discovery' mechanism you describe above. > o) OPTIONAL COP <snip/> > TODO > ---- > <snip/> > 3) Which avalon container should we use since the one we currently use > (ECM) is not powerful enough? is there already a container which is > powerful enough to handle our needs as described here? if not, what do > we do? we implement our own or work with the avalon people to fix theirs > to meet our needs? I agree, ECM isn't powerful enough to handle all this. The 2 new Avalon containers are Fortress and Merlin. It would be great if there was some synergy between Avalon & Cocoon to develop/improve one/both of these containers to be suitable for use in Cocoon, rather than implement our own. Merlin offers better support for the meta-info approach to managing components and container hierarchies, whereas Fortress offers better ECM style compatibility. Both don't yet handle package level dependancies but I don't see any problems adding that. The choice of container is important though as a lot of what you describe could be container concerns rather than application concerns (eg. package validation, versioning, classloader management, etc). Having most of that at the container level makes it much easier for Cocoon which would then become the essential core, blocks, and perhaps any required container extensions, etc. This is where 2.1 has suffered IMO, as the 2.1 codebase includes features that IMO should really be handled at the container level (eg. extra avalon lifecycles, configuration file monitoring, sitemap/subsitap -> container hierarchy management, etc). Perhaps we need to investigate a bit deeper into what the container should do for us. This will allow selection of which container to be a bit easier. Once I get our admin app up and running here at the bank I'd be happy to look deeper into this. <snip/> One other thing: 7) Backwards compatibility, how will it be retained ? All looks great Stefano so far. Look forward to any comments you may have. Cheers, Marcus -- ..... ,,$$$$$$$$$, Marcus Crafter ;$' '$$$$: Computer Systems Engineer $: $$$$: ManageSoft GmbH $ o_)$$$: 82-84 Mainzer Landstrasse ;$, _/\ &&:' 60327 Frankfurt Germany ' /( &&& \_&&&&' &&&&. &&&&&&&: --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]