Return-Path: Delivered-To: apmail-jakarta-avalon-dev-archive@apache.org Received: (qmail 63958 invoked from network); 29 Aug 2002 14:24:54 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 29 Aug 2002 14:24:54 -0000 Received: (qmail 4497 invoked by uid 97); 29 Aug 2002 14:25:23 -0000 Delivered-To: qmlist-jakarta-archive-avalon-dev@jakarta.apache.org Received: (qmail 4453 invoked by uid 97); 29 Aug 2002 14:25:22 -0000 Mailing-List: contact avalon-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon Developers List" Reply-To: "Avalon Developers List" Delivered-To: mailing list avalon-dev@jakarta.apache.org Received: (qmail 4441 invoked by uid 98); 29 Aug 2002 14:25:21 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Reply-To: From: "Berin Loritsch" To: "Avalon Developer's List" Subject: [RT] Management vs. Component Resolution Date: Thu, 29 Aug 2002 10:24:45 -0400 Message-ID: <002e01c24f67$d2fa25b0$ac00a8c0@Gabriel> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook, Build 10.0.2627 Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N 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: For additional commands, e-mail: