You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Stephen McConnell <mc...@apache.org> on 2002/12/07 20:42:10 UTC

Re: Context: usage recommendations?

I've read with a lot of interest the thoughts and requirements coming 
out of this thread - in particular the comments from Daz, Gary, and 
Adam.  One of comments that I found profound but obvious was the 
observation that current concepts/thinking is very container 
architecture driven.  I've been thinking and thinking about this and 
I've reached some sort of a conclusion that would enable the end user to 
express component relationships independently of the context/service split.

The the avalon-sandbox info and meta packages both force the container 
driven perspective on context/service separation - and I've come to the 
conclusion the (a) this is not needed, and (b) that potable context can 
be provided - if we rehash the meta model.


If you familiar with either the info or meta package you will be aware 
of the following pattern:

   [meta-info-for-component]

      * [general-info-block]
      * [context-block]
      * [services-provided-block]
      * [service-dependencies-block]

I'm starting to think about an alternative approach.  I've identified 
three distinct groups that can be both consumed and provided (from a 
container perspective).  These include the following:

  * Service providers

    These are the classic services that can be assembled
    based on consumption and production declarations.

  * Service locator

    This is a new concept that is very similar to the
    Merlin extension handler.  It a component that provides
    a plug-in lookup solution that can be narrowed to a
    particular interface (and can be located by the container
    using the interface name as the key). A service locator
    can be applied to the following three areas:

      * context value lookup
      * service lookup
      * lifecycle stage handler lookup

If we re-examine things from the the component authors perspective, it 
seems reasonable to describe the mapping of a service, context and 
lifecycle in terms of production and consumption relationships.

   [meta-info]

      * [general-info]
      * [consumption-info]
      * [production-info]

 From this model we can esily map in the container view of the world by 
doing something like the following:

   [meta-info]

      * [general-info]
      * [consumption-info]
           * [context]
                * [service-dependencies]
                * [locator-dependencies]
           * [service]
                * [services-dependencies]
                * [locator-dependencies]
           * [lifecycle]
                * [stage-dependencies]
      * [production-info]
           * [service-provision]
           * [locator-provision]
           * [stage-provision]


What's interesting about the above is that (a) the object model for 
context and service is parallel.  This means that the client can narrow 
a supplied context instance to a particular interface, and can do the 
same thing with a supplied service manager. The container author can 
forget about declaring typed context entries, and instead, he/she can 
simply declare a set of locator dependencies - e.g. an author may want a 
BlockContext locator and a MailetContext locator. The container can 
handle the establishment of the respective context and service managers 
so that any pure key based request still map to the appropriate locator 
and any casting against interfaces supported by the set of associated 
locators can be wrapped in a composite proxy.

A second interesting point is that the component author has 100% control 
over which services and locators are mapped to the context abstraction 
as opposed to the service abstraction.  The component author would be to 
include totally different locators into a single context without any 
client side impact relative to current framework interfaces.  And most 
importantly, the entire models can portable across containers that 
support a standard locator object model.

 From the container authors point of view locators can be treated as 
components and as such that can have their own dependencies.  This means 
that something like a BlockContext locator can plugged into the system 
and the container simply assembles it and assigns it as appropriate.

A complete DTD for component model on the above with both consumption 
and production features would look something like:

  <type>

    <info name="demo" version="2.0"/>

    <consumes>

      <lifecycle>
        <stage type="org.demo.Demonstratable"/>
      </lifecycle>

      <context>
        <locator type="org.a.a.f.context.SystemLocator" version="4.1.2"/>
        <locator type="org.a.j.MailetLocator" version="2"/>
        <service type="org.demo.SimpleService" key="simple" version="1"/>
      </context>

      <services>
        <service type="org.demo.Store" key="vault"/>
        <locator type="org.demo.SecurityLocator" version="4.1.2"/>
      <services>

    </consumes>

    <produces>

      <service type="org.demo.PathResolver" version="3.2" />
      <locator type="org.demo.Directory" />
      <stage type="org.demo.Exploitable" version=2"/>

    </produces>

  </type>

 From the point of view of current framework interfaces, it would be 
feasible to incorporate a framework level Locator interface as a 
super-type of both ServiceManager and Context so that operations on the 
supplied parameter to contextualize and service could be treated in the 
same way.  It would even be possible to incorporate migration interfaces 
into 4.2 version of Contextulizable and Serviceable under which a 
Locator is passed as the parameter.

E.g.

   public void contextualize( Locator locator ) throws LocatorException
   {
       SystemLocator system = (SystemLocator) locator;
       File base = system.getWorkingDirectory();
       m_name = locator.locate( "urn:avalon:name" );
   }
 
   public void service( Locator locator ) throws LocatorException
   {
       SecurityLocator sec = (SecurityLocator) locator;
       Privalege[] sec.getPrivaliges( m_name );
       // etc.
   }
 
 From here, the differentiating factor between contextualization and 
services phases is reduced to the ordered sequence in the lifecycle.

Any thoughts ?



Darrell DeBoer wrote:

>Thanks Gary,
>
>It's funny, I woke up this morning with a similar conclusion. Yesterday, for 
>the first time, I could see both Peter's and Stephen's arguments for a 
>distinction between Container-supplied and Peer-supplied services (or 
>"(non)priviledged" as Stephen is calling the distinction).
>
>The problem with both of these distinctions is that they are about Container 
>implementation. My take on it is thus:
>
>Peter wants to distinguish Container-provided services, because the person 
>doing the assembly doesn't have to specify them in the assembly file. 
>Unfortunately, it's quite easy to imagine one container which provides a 
>certain service directly, and a different one which requries a 
>user-configured component to provide the same service. So by distinguishing 
>between these in *code*, the component will be inherently non-portable. 
>(Whereas the assembly file can be thought of as container-specific? - At 
>least it's easy to change for a new deployment).
>
>Stephen wants to have the notion of priviledged services, so he can implement 
>life-cycle handlers and context providers as components (at least this is 
>what I've garnered from the emails, I don't know the code). While this sounds 
>cool from the design perspective, it seems like this notion should be kept 
>out of Framework, as it's a specific requirement of the Merlin container. 
>Other containers may want to provide extensibility in a completely different 
>way (maybe the "interceptors" Pete has eluded to fall into this). What 
>follows is that regular components which rely just on Framework contracts 
>will be portable, whereas Merlin lifecycle extension components don't need to 
>be, so they can use a Merlin-specific contracts and interfaces.
>
>(Who says having competing container implementations is a bad thing? ;)
>
>This example is giving me a few troubles:
>  
>
>>>getServletContext().isPrincipleInRole( String role, Principle p );
>>>getSessionContext().isCallerInRole( String role );
>>>      
>>>
>
>These are container provided services, and it would "feel" right that they 
>would be split out from the provision of other services. But then you 
>realise: - these interfaces are defined as part of a specification. The 
>container can't choose whether or not to provides these things, they are 
>required. And the container can't arbitrarily provide new stuff in this way, 
>since then a component would become non-portable.
>
>So I can't see the argument for the Container-provided/Peer-provided divide. 
>But I can see an argument for a logical and code separation of services 
>defined in the spec (and therefore part of the Avalon-Framework contracts), 
>and other services (both container and peer).
>
>At the moment, I don't think any such services exist. Maybe we should come up 
>with some, and *maybe* they should be provided in a separate mechanism to 
>regular services. But since they are part of the spec, components won't need 
>to "declare" the context they require, and things like MailetContext and 
>ServletContext are removed from these arguments, since they aren't part of 
>the Avalon-Framework contracts.
>
>This is my take on the matter, anyhow.
>
>ciao
>Daz
>
>On Thu, 5 Dec 2002 04:05, Gary Shea wrote:
>  
>
>>I've been following this thread with a great deal of interest, since I
>>have the same questions as Adam has been asking.  My experience with
>>using Avalon is that Context is great until you get someone else's
>>container involved in the picture.  At that point it becomes a minor
>>nightmare, since each container sees it differently.
>>
>>My views are from the perspective of a component writer who wants to
>>avoid container lock-in.
>>
>>I've been willing to adopt the data/services distinction, because the
>>container I want to use (merlin) does so.  But the data/services
>>paradigm turns Context into either a less-capable Configuration or a
>>declaratively-driven object builder.  The idea of Context as an object
>>builder feels kind of baroque to me, and I can't imagine that all
>>containers will do it, so in merlin I don't use Context at all.
>>
>>The container-provided/peer-provided view is one I'd be willing to adopt
>>also.  In this view, Context is container-dependent, and is simply
>>anathema to the component writer who wants to maintain cross-container
>>portability.  That's the extent of my interest.  I can see how this
>>view would be useful to someone building a tightly-coupled
>>component/container system, but my goal is to avoid that at all costs.
>>
>>As you can see, I wouldn't use Context under either of the data/service
>>or container/peer paradigms.  I think that's ok.
>>
>>If this discussion had to end today, I'd say Context is a red herring
>>and should be discarded.  It would be replaced with two new stages:
>>ObjectConfigurable and ContainerServiceable.
>>
>>        Gary
>>
>>[2002-12-04 21:56 +1100] Peter Donald (peter@realityforge.org) wrote:
>>    
>>
>>>On Wed, 4 Dec 2002 11:07, Adam Murdoch wrote:
>>>      
>>>
>>>>These are useful things, no question.  Components need some way to get
>>>>at data and services that are supplied by the container.  Again, why do
>>>>they care that a particular service or piece of data was supplied by
>>>>the container or a peer?
>>>>        
>>>>
>>>Components don't care what the origins of the resource are - all of it is
>>>potentially "contextualized" on a per component basis and all generally
>>>has certain criteria to adhere to but beyond that it is about it. The
>>>different resources are separated out for the sake of humans and no other
>>>reason.
>>>
>>>Context is separated from ServiceManager because humans see them as
>>>different things - especially during the assembly process.
>>>
>>>      
>>>
>>>>Yes, I know that they're "different logical things".  But so are, say,
>>>>authentication services and persistence services.  We don't use
>>>>different mechanisms to deliver those services to components.  It would
>>>>be pointless to do so:
>>>>        
>>>>
>>>I disagree. If persistence were provided to the component and the
>>>component was effectively made to be an OJB object or something like that
>>>then we would likely provide persistence/transaction capabilities in a
>>>very different manner. Most likely via some transparent EJB-like manner.
>>>
>>>In the same way if AAA services were provided to a component as part of
>>>it's environment then it would likely also follow an EJB/Servlet style
>>>setup where the container does it via interception and allows components
>>>to access it programatically via something like
>>>
>>>getServletContext().isPrincipleInRole( String role, Principle p );
>>>getSessionContext().isCallerInRole( String role );
>>>(or insert real examples here or JAAS).
>>>
>>>If the services are things that the container provides to the component
>>>as part of it's environment then the user perceives them as different to
>>>services that the component uses. I can't think of one API that actually
>>>merges the two concepts.
>>>
>>>When we tried to merge the two things together the primary reason we
>>>separated them out again was because of user complaints. ie If a
>>>resources requires resources A, B and C and C is container provided. All
>>>three are accessed in the same way so the person sees them as much the
>>>same (like the component sees them as much the same). However during
>>>assembly they are only required to assemble A and B - which creates a
>>>cognitive dissonance because they are treated as identical in one place
>>>but different in another.
>>>
>>>      
>>>
>>>>So which of these cases do you think offer the most benefit to the
>>>>component writer?  Assume logger, config, params have been split out
>>>>already: 1. No separation.
>>>>2. Separate data and services.
>>>>3. Separate container-provided resources and peer-provided resources.
>>>>        
>>>>
>>>+1
>>>
>>>      
>>>
>>>>4. Separate container-provided data, container-provided services,
>>>>peer-provided data, and peer-provided services.
>>>>5. Who cares?  Why are you bothering me with these questions?
>>>>
>>>>        
>>>>
>>>:)
>>>
>>>--
>>>Cheers,
>>>
>>>Peter Donald
>>>*------------------------------------------------*
>>>
>>>| Those who know how to think need no teachers.  |
>>>|                                      - Gandhi  |
>>>
>>>*------------------------------------------------*
>>>
>>>
>>>--
>>>To unsubscribe, e-mail:  
>>><ma...@jakarta.apache.org> For additional
>>>commands, e-mail: <ma...@jakarta.apache.org>
>>>      
>>>
>
>
>--
>To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
>For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>
>
>  
>

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Context: usage recommendations?

Posted by Stephen McConnell <mc...@apache.org>.

Adam Murdoch wrote:

>Hi,
>
>It would be really useful to take a step back, and first figure out *what* a 
>Context is, and *what* a ServiceManager.  Let's leave figuring out *how* to 
>populate them until we know what they are.  We don't even know whether 
>they're distinct things yet.
>  
>

If you take out the container constraint of "what is a context supplied 
object" you left with lifecycle aspects as the only distinguishing feature.

>For example, the only real answer to the 'what is the difference between a 
>context and a service manager?' question I've had so far is 'they're 
>different because people think of them as different things'.  Which is fine, 
>except no-one seems to be able to explain what the difference is, and why 
>that difference is important enough to model in framework.
>
>This is the crux of the matter.  Not whether it's *possible* to make the 
>distinction, but whether it is *useful* to make the distinction.  Maybe it 
>is, maybe it isn't.  (Hint: the distinction must be meaningful across *all* 
>containers.  It can't be "well, it means this sometimes, and it means that at 
>other times").
>
>I also wonder how much of "people think of them as different things" is due to 
>the fact that framework has a thing called "Context" and another thing called 
>"ServiceManager", and "well .. um .. of course they're different things, 
>otherwise they wouldn't be there".  In other words, are we trying to invent a 
>meaning for Context because Context currently happens to be part of 
>framework?
>  
>

I can't argue against this!

>On Sun, 8 Dec 2002 05:42 am, Stephen McConnell wrote:
>
>  
>
>>A second interesting point is that the component author has 100% control
>>over which services and locators are mapped to the context abstraction
>>as opposed to the service abstraction.  
>>    
>>
>
>and later:
>
>  
>
>> From here, the differentiating factor between contextualization and
>>services phases is reduced to the ordered sequence in the lifecycle.
>>    
>>
>
>But service() is called immediately after contextualize().  How is it useful 
>for the component writer to be able to map resources between these methods 
>when they're called one-after-the-other?  Why bother?  
>

Because I feel real comfortable with the destinction - and the 
distinction I'm applying is data centric versus service centric - and 
yes their both objects - but that's not important - what's important is 
that it feels right.

:-)

>Surely it would be 
>easier for everyone involved to simply collapse those 2 methods?
>  
>

Aside from feeling good, this gets into the "Recontextualizable" area. 
 In just about all of the components I work with, the context values 
tend to be the state that the components uses relative to a set of 
underlying services, combined with its own logic.

I have several specific instances of components that could benefit 
greatly by container supplied recontextualization.  The service mapping 
remains the same - only the data supplied to the component changes.

Consider the following sequence:

   -> contextualize
   -> service
   -> initialize
   -> start

      ... stuff happens

   -> suspend
   -> recontextualize
   -> resume

      ... stuff happens

   -> stop
   -> dispose

Cheers, Steve.


-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Context: usage recommendations?

Posted by Adam Murdoch <ad...@apache.org>.
Hi,

It would be really useful to take a step back, and first figure out *what* a 
Context is, and *what* a ServiceManager.  Let's leave figuring out *how* to 
populate them until we know what they are.  We don't even know whether 
they're distinct things yet.

For example, the only real answer to the 'what is the difference between a 
context and a service manager?' question I've had so far is 'they're 
different because people think of them as different things'.  Which is fine, 
except no-one seems to be able to explain what the difference is, and why 
that difference is important enough to model in framework.

This is the crux of the matter.  Not whether it's *possible* to make the 
distinction, but whether it is *useful* to make the distinction.  Maybe it 
is, maybe it isn't.  (Hint: the distinction must be meaningful across *all* 
containers.  It can't be "well, it means this sometimes, and it means that at 
other times").

I also wonder how much of "people think of them as different things" is due to 
the fact that framework has a thing called "Context" and another thing called 
"ServiceManager", and "well .. um .. of course they're different things, 
otherwise they wouldn't be there".  In other words, are we trying to invent a 
meaning for Context because Context currently happens to be part of 
framework?

On Sun, 8 Dec 2002 05:42 am, Stephen McConnell wrote:

> A second interesting point is that the component author has 100% control
> over which services and locators are mapped to the context abstraction
> as opposed to the service abstraction.  

and later:

>  From here, the differentiating factor between contextualization and
> services phases is reduced to the ordered sequence in the lifecycle.

But service() is called immediately after contextualize().  How is it useful 
for the component writer to be able to map resources between these methods 
when they're called one-after-the-other?  Why bother?  Surely it would be 
easier for everyone involved to simply collapse those 2 methods?

-- 
Adam

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>