avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Berin Loritsch" <blorit...@apache.org>
Subject [RT] Management vs. Component Resolution
Date Thu, 29 Aug 2002 14:24:45 GMT
Considering the last thread about the Merlin Container design, I have
some
thoughts that will help sum up the differences between exposing
management
services and resolving components.  It would be good to get everyone's
comments on it.

What we have are two diverging needs for our components.  We need the
ability
to interact with certain components differently than other components.
The
typical type of component that is dealt with differently is (for lack of
a
better word) a "Management Component".  A Management Component takes
care of
the interactions between clients who need to control a subsystem, and
the
subsystem they protect.

There are three basic approaches that are taken to solve the issue: J2EE
style, Dual Purpose Component Style, and Publishing Style.  They have
different
pros and cons.  We want to maintain isolation between container levels
for
security reasons, as well as for containment reasons.  Below we will
show
the differences:


                          -o0 J2EE Style 0o-

J2EE basically has a nearly flat container space.  Within J2EE is a
Servlet
engine, an EJB engine, hooks to MOM (Messaging Oriented Middleware), and
more.  To make things simpler on the developer there are certain APIs
you are
supposed to use like JavaMail if you want to send or read messages.
Each of
the major containers live within an Application container (or server if
you prefer).  The Application Container begins by binding child JNDI
contexts
to its root JNDI context--one for each child container.  The child
container
then binds all the exposed services that it supports.

The decision process over which service gets bound to JNDI depends on
the
deployment descriptors and the complex assembly logic.  Once all
services
are bound to the JNDI context, the context becomes read only, and the
system
moves on.

Whether this is the way the internals of any particular J2EE container
truly
work or not doesn't matter.  It is what is logically happening.  Any
client
can access any service bound to JNDI through the root JNDI context.
That
is why J2EE has a lookup namespace like this:
"java://${container}/${service}".
It does also bind configuration information to JNDI, etc. but that has
nothing
to do with what we are talking about.

THE CLOSEST CONTAINER we have to behave like J2EE is Phoenix.  It does
expose
management interfaces using JMX, which is a good thing.  What Phoenix
does
behind the scenes (please correct me if I am wrong) is that it sets up
different
isolated spaces for each hosted app.  All components in all applications
are
all contained by the Phoenix container, so it can use the Scheduler from
one
application to service another application without violating IoC or
other
principles.  It uses complex assembly and service resolution logic to
determine
what each component is *allowed* to see, and only exposes those services
to that component.  That is proper design, with an eye on security.


                 -o0 Dual Purpose Component Style 0o-

A dual purpose component is a component that acts as both a container
and a
component.  Examples of this is what Cocoon does, and what InfoMover
will do.
The "Management Component" is a container.  It contains all the
components
it is managing, and the interface to interact with the container is on
the
container itself.  This is a simple way of providing containment as well
as
"publishing" the interface of how to control the subsystem.

The consequences of this approach is that all the components contained
by
the dual purpose component (i.e. component IS A container) is that you
expose
the interface to interact with the subsestem without exposing anything
it
does not want to expose.  This approach provides the most control over
what gets exposed, and where.

There are a couple of variations on this approach.  One variation is to
expose the interface to a separate component that talks to the true
container.
Another variation is to allow the container/component control access to
its
internal components.

For example, if I decided to set up InfoMover's container to ask for a
Job,
and then all actions on that job were executed directly then I use
InfoMover's
JobManager as a typesafe component selector.  This is an effective way
of
exposing management functions to internal components that would
otherwise
be completely isolated.  In practice, I would not return the actual Job,
but
a proxy to that Job.


                      -o0 Publication Style 0o-

The publication style is the approach that I *think* Stephen and one of
the
Leo's are advocating.  Basically, the publication approach exposes a
controlled
set of services to a parent component to allow resolution of the
service.
The major problem with the publication style is that once you publish an
interface, you loose control over who else gets to see it.

To provide an example of the publishing style pitfall, lets use the
container
hierarchy of "root/sub2/child1/end".  If the "end" container decided to
publish
a service to its parent, it looses control at that point.  It could be
that
"end" intended for that service to be used in "root/sub2/child2", in
which case
it would expect "child1" to republish the same service.  The problem
comes when
"child1" republishes, and "sub2" republishes it, and finally it is
accessible
at the "root" level.  This is bad.

Another point to consider with the "publish" style is that it must be
done
*safely*.  That means we only publish a proxy to the service, and the
proxy
has to be able to determine if the client is legally permitted to use
the service.
Also, the publication mechanism should not be on the Container interface
at all.
It should be moved to a separate interface, and publication accomplished
much like
the ServiceManager works today.

The ServiceManager is a peer to both the container and the client,
however it
affectively isolates the two so that the client cannot directly control
the
container.  We would need a ServicePublisher that the child container
would
use to publish the service and its proxy to the parent container.
Another
important aspect is that the publishing mechanism cannot override the
natural
inheritance style selection.  All it can do is raise the level where a
service
is accessible from.  If a parent can already handle a published service,
it
does not need to use the published service at all.  Those decisions
would be
an assembly level issue if there are mitigating circumstances when a
published
service must be used in preference to the existing implemenation.


                       -o0 The Conclusion 0o-

Service publication is an extension to the contracts already in place
for
containers, so we cannot expect others to jump on the bandwagon.
Therefore,
you would possibly be able to embed Merlin inside Phoenix, but I doubt
that
Phoenix would ever support the extension.  I really don't think it
should,
because Phoenix is designed to be a root level container, not an
embedded
one.

The best options are to use JNDI to publish all the services in a global
namespace like the J2EE style, or to use the dual purpose component
style.
Both have their tradeoffs, but they both would be able to be used in any
container system without serious redesign issues.


"They that give up essential liberty to obtain a little temporary safety
 deserve neither liberty nor safety."
                - Benjamin Franklin


--
To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.org>


Mime
View raw message