-----Original Message-----
From: Stephen McConnell [mailto:[EMAIL PROTECTED]
Sent: Wednesday, November 14, 2001 11:35 PM
To: Avalon Developers List
Subject: RE: Interfaces=Services / dependencies?
Hans:
A bunch of note in-line.
Hans Herbert wrote:
I am new at this Mailinglist and hope that my questions are not
too stupid.
[sniped example]
Don't worry - getting the hang of the assembly, manifest and xinfo stuff
takes a little while. I've snipped out your example and instead I'm
including an example below of a real .xinfo file and further down an
extract of an assembly.xml file - together with some comments.
Here is a .xinfo file for a reasonably simple block that serves as a
factory for business processes the handle PKI certification request.
I've added comments in line to explain what's going on.
<blockinfo>
<block>
<version>1.0</version>
</block>
<services>
<!--
This block could be declaring several services that it supports.
Unlike an Java interface, the service includes a version tag. So
its possible for a block to several services with possibly
different versions. If there are multiple services then just
declare them with multiple service entries here. Phoenix will make
sure that the class with the same name as the .xinfo file
implements these interfaces (if it doesn't then Phoenix will
terminate)
-->
<service name="net.osm.hub.gateway.FactoryService" version="1.0" />
</services>
<!--
So far, we have the definition of a class that supports possibly
multiple version interface. But things get much more interesting when
we think about the services that this block requires in order to function
properly. That's partly handled by the dependencies element and partly by
the assempbly.xml file (which I'll explain later). I the following
dependency example there are seven "service" dependencies (i.e. 7
versioned
interface dependencies that must be fulfilled for this block to function.
-->
<dependencies>
<!--
Each dependency contains a declaration of a role name and the
the service interface and version that can fulfil that role. The
dependency does not say anything about where that service
implementation should come from (that's the job the assembly.xml
file). The role element is simply the label used in the implementation
of your block configure method that distinguishes a particular
instance of the service.
-->
<dependency>
<role>GATEWAY</role>
<service name="net.osm.hub.gateway.GatewayContext" version="1.0"/>
</dependency>
<!--
This dependency declaration simply states that in order to function,
this
block requires an a "service" (which happens to a wrapper to a CORBA
ORB version 2.4) and that the block implementation will lookup that
service using the "ORB" keyword.
-->
<dependency>
<role>ORB</role>
<service name="net.osm.hub.gateway.ORBService" version="2.4"/>
</dependency>
<!--
This dependency declares a requirement for a PSS (Persistent State
Service) Storage Home.
-->
<dependency>
<role>PSS</role>
<service name="net.osm.hub.gateway.ProcessorStorageHomeService"
version="1.0"/>
</dependency>
<!--
This dependency enables the block to establish a call-back to the
block supplying the service. This block uses the Registry interface
to publish a business process description to a higher level manager.
-->
<dependency>
<role>REGISTRY</role>
<service name="net.osm.hub.gateway.Registry" version="1.0"/>
</dependency>
<!-- etc. -->
<dependency>
<role>DOMAIN</role>
<service name="net.osm.hub.gateway.DomainService" version="1.0"/>
</dependency>
<dependency>
<role>RANDOM</role>
<service name="net.osm.hub.gateway.RandomService" version="1.0"/>
</dependency>
<dependency>
<role>CLOCK</role>
<service name="net.osm.service.time.TimeService" version="1.0"/>
</dependency>
</dependencies>
</blockinfo>
Here is a block declaration I've cut from an assembly.xml file. This enables
the declaration of WHERE the services are coming from. I.e. you may have a
system with many blocks and even the potential for matching services
available
from more that one block. The class attribute provides the link to the
.xinfo
file and the implementation class. The name is used a key within the
assembly.xml file when wiring things together. E.g. the provide element
references a block by its name - and declares that the named block will
serve
as the provider of the service. The role attribute matches the role element
in the .xinfo dependency declaration.
<!-- Certification Request Factory -->
<block class="net.osm.pki.process.CertificationRequestServer"
name="certification" >
<provide name="gateway" role="GATEWAY"/>
<provide name="gateway" role="ORB"/>
<provide name="gateway" role="PSS"/>
<provide name="gateway" role="DOMAIN"/>
<provide name="gateway" role="RANDOM"/>
<provide name="pki" role="REGISTRY"/>
<provide name="time" role="CLOCK"/>
</block>
Now the question: Isn't that some kind of double information. I
tried some different configuration, but it seems that it has to
be that way.
- What is the advantage/idea behind this?
First of all it forces structure and separation, secondly, it provides a way
of managing possibly multiple versions of the same interface in a single
environment. Thirdly, it enables explicit declaration of the source of
service provision. For example, in the OSM platform we have multiple blocks
providing a TimeService. One of those blocks uses an external time
reference while the others use a local time reference. The local time block
declare dependencies on the external source time block and periodically
synchronised. In this example all of the TimeService services are exposing
the same interface, same version (i.e. same service), but the decision as to
which service is the provider to another can be explicitly controlled.
While the time example is perhaps trivial, there are significant policy
security implications related to service provider selection.
I found your last answer regarding the BlockListener and "Linking
Interfaces to a Block". How can I implement this in my code?
To create a block listener you need to do the following:
1. declare the listener in the assembly.xml file
<avalon>
<block-listener name="myListener" class="MyClass" />
<!--
and any other stuff
-->
</avalon>
2. implement the listener
public class MyClass
implements BlockListener
{
public void blockAdded( BlockEvent event )
{
System.err.printl( "ADDED " + event.getName() )
}
public void blockRemoved( BlockEvent event )
{
System.err.printl( "REMOVED " + event.getName() )
}
}
3. make sure the listener is included in a jar file in
the ${SAR-INF}/lib directory.
An I think that about it.
Let's say, I have a Block that would like to communicate with all
the other blocks via interfaces (of course). Either I write all these
Blocks and
interfaces in that above described way OR I say the Block "He, if a Block
implements your interface, this Block wants to talk to you.
You could do that but I would recommend using the formal .xinfo/assembly.xml
approach because (a) are getting much more rigorous about the relationships
between blocks, and (b) you get lifecycle support, dependency validation,
and
things like resource establishment for free courtesy of Phoenix block
lifecycle
management.
So start a lookup at this Block using the componentManager.lookup(ROLE)".
- Is it possible to do such a checking during starting up without writing
all down in assembly and xinfo?
No.
This would be a much more flexible way of linking (my opinion)
Absolutely - much more flexible, much easier to put together, and much less
reliable. :-)
Cheers, Steve.
Stephen J. McConnell, OSM sarl
digital products for a global economy
http://www.osm.net
mailto:[EMAIL PROTECTED]
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>