mcconnell 2003/04/05 03:54:27
Modified: merlin/merlin-smp project.properties project.xml
merlin/merlin-smp/xdocs navigation.xml
merlin/merlin-smp/xdocs/about navigation.xml
merlin/merlin-smp/xdocs/starting/advanced profiles.xml
selectors.xml
Log:
Pluggable Profile selection policy tutorial.
Revision Changes Path
1.3 +1 -1 avalon-sandbox/merlin/merlin-smp/project.properties
Index: project.properties
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/merlin-smp/project.properties,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- project.properties 13 Mar 2003 03:52:32 -0000 1.2
+++ project.properties 5 Apr 2003 11:54:27 -0000 1.3
@@ -15,7 +15,7 @@
sun.j2se.link = http://java.sun.com/j2se/1.4/docs/api/
avalon.framework.link = http://avalon.apache.org/framework/api/
avalon.logkit.link = http://avalon.apache.org/logkit/api/
-avalon.lifecycle.link = http://avalon.apache.org/lifecycle/api/
+avalon.lifecycle.link = http://avalon.apache.org/sandbox/lifecycle/api/
excalibur.configuration.link = http://avalon.apache.org/excalibur/configuration/api/
excalibur.pool.link = http://avalon.apache.org/excalibur/pool/api/
excalibur.thread.link = http://avalon.apache.org/excalibur/thread/api/
1.6 +1 -1 avalon-sandbox/merlin/merlin-smp/project.xml
Index: project.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/merlin-smp/project.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- project.xml 4 Apr 2003 15:49:44 -0000 1.5
+++ project.xml 5 Apr 2003 11:54:27 -0000 1.6
@@ -105,7 +105,7 @@
</packageGroups>
<reports>
- <report>maven-javadoc-plugin</report>
+ <!--<report>maven-javadoc-plugin</report>-->
<report>maven-jdepend-plugin</report>
<report>maven-changelog-plugin</report>
<report>maven-file-activity-plugin</report>
1.5 +1 -1 avalon-sandbox/merlin/merlin-smp/xdocs/navigation.xml
Index: navigation.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/merlin-smp/xdocs/navigation.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- navigation.xml 2 Apr 2003 21:57:58 -0000 1.4
+++ navigation.xml 5 Apr 2003 11:54:27 -0000 1.5
@@ -11,7 +11,7 @@
</links>
<menu name="About Merlin">
- <item name="Overview" href="/index.html"/>
+ <item name="Overview" href="/about/index.html"/>
<item name="Getting Started" href="/starting/index.html"/>
<item name="Merlin System" href="/merlin/index.html"/>
<item name="Meta Model" href="/meta/index.html"/>
1.3 +1 -1 avalon-sandbox/merlin/merlin-smp/xdocs/about/navigation.xml
Index: navigation.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/merlin-smp/xdocs/about/navigation.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- navigation.xml 2 Apr 2003 21:57:58 -0000 1.2
+++ navigation.xml 5 Apr 2003 11:54:27 -0000 1.3
@@ -10,7 +10,7 @@
</links>
<menu name="About Merlin">
- <item name="Overview" href="/about/index.html">
+ <item name="Overview" href="/index.html">
<item name="Purpose" href="/about/purpose.html"/>
<item name="Features" href="/about/features.html"/>
<item name="Benefits" href="/about/benefits.html"/>
1.2 +124 -1
avalon-sandbox/merlin/merlin-smp/xdocs/starting/advanced/profiles.xml
Index: profiles.xml
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/merlin-smp/xdocs/starting/advanced/profiles.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- profiles.xml 2 Apr 2003 15:52:16 -0000 1.1
+++ profiles.xml 5 Apr 2003 11:54:27 -0000 1.2
@@ -10,8 +10,131 @@
<body>
<section name="Advanced Features">
<subsection name="Packaged Deployment Profiles">
- <p>In preparation.</p>
+ <p>
+ Central to the Merlin component management model is the notion
+ deployment profiles. A profile is a prefined deployment template.
+ It enables Merlin to establish a component type and associated
+ context, parameterization and/or configuration information as a
+ candidate scenario when building a connected set of commponents.
+ </p>
+ <p>
+ Component deployment profiles are co-located with the component
+ implementation class under a .xprofile resource.
+ </p>
</subsection>
+ <subsection name="Creating a Profile">
+ <p>
+ This tutorial extends the interfaces, classes and meta info
+ declared in the <a href="../hello/dependencies.html">dependencies
tutorial</a>
+ by adding a configurable seed value to the RandomGenerator component.
Without
+ the benefit of a profile, users would be forced to declare a
configuration
+ under the block.xml directive. By providing one or more profiles, we
enable
+ Merlin to automatically select a deployment scenario candidate and use
this
+ during the assembly phase.
+ </p>
+ <p>
+ The RandomGeneratorProvider source and the corresponding profile directive
+ is presented below.
+ </p>
+ <p><i>RandomGeneratorProvider.java</i></p>
+<source>
+
+package tutorial;
+
+import java.util.Random;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+/**
+ * An implementation of a random number generator.
+ */
+public class RandomGeneratorProvider extends AbstractLogEnabled
+ implements Configurable, RandomGenerator
+{
+
+ private Random m_random = null;
+
+ /**
+ * Configuration of the component by the container. The
+ * implementation get a child element named 'source' and
+ * assigns the value of the element to a local variable.
+ *
+ * @param config the component configuration
+ * @exception ConfigurationException if a configuration error occurs
+ */
+ public void configure( Configuration config ) throws ConfigurationException
+ {
+ getLogger().info( "configuration stage" );
+ long seed = config.getChild( "seed" ).getValueAsLong( 0 );
+ getLogger().info( "seed: " + seed );
+ m_random = new Random( System.currentTimeMillis() * seed );
+ }
+
+ /**
+ * Return a random integer
+ * @return the random number
+ */
+ public int getRandom()
+ {
+ return m_random.nextInt();
+ }
+}
+</source>
+ <p>
+ The RandomGeneratorProvider.xprofile contains the defintion of multiple
tagged
+ deployment scenarios. During assembly Merlin will attempt to locate an
explicit
+ deployment profile (a compoennt declaration in the block.xml). In no
explicit
+ profile is available Merlin will select a packaged profile based on the
xprofile
+ declarations, otherwise Merlin will attempt to construct an implict
profile.
+ </p>
+ <p><i>RandomGeneratorProvider.xprofile</i></p>
+<source><![CDATA[
+<?xml version="1.0"?>
+
+<profiles>
+ <profile name="randomizer">
+ <configuration>
+ <seed>1024</seed>
+ </configuration>
+ </profile>
+</profiles>
+]]></source>
+ </subsection>
+ <subsection name="Executing the tutorial">
+ <p>
+ Build and run the tutorial.
+ </p>
+ <source>
+$ ant
+$ merlin build\classes
+ </source>
+ <p>
+ In the logging output we see that Merlin has automatically
+ locating the RandomGeneratorProvider using the packaged profile.
+ </p>
+<source>
+[INFO ] (tutorial.hello.random-provider#randomizer): configuration stage
+[INFO ] (tutorial.hello.random-provider#randomizer): seed: 1024
+[INFO ] (tutorial.hello): random: 6608684
+</source>
+ <p>
+ Note: When constructing an name for the component based on a
+ packaged profile, Merlin will append the component type name to the
+ profile name, seperated by the # character resulting in the
+ compoennt name 'random-provider#randomizer'.
+ </p>
+
+ </subsection>
+ <subsection name="Profile selection">
+ <p>
+ The <a href="selectors.html">next tutorial</a> describes the
+ mechansims used to influence profile selection within Merlin.
+ </p>
+ </subsection>
+
</section>
</body>
1.2 +167 -2
avalon-sandbox/merlin/merlin-smp/xdocs/starting/advanced/selectors.xml
Index: selectors.xml
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/merlin-smp/xdocs/starting/advanced/selectors.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- selectors.xml 2 Apr 2003 15:52:16 -0000 1.1
+++ selectors.xml 5 Apr 2003 11:54:27 -0000 1.2
@@ -9,8 +9,173 @@
</header>
<body>
<section name="Advanced Features">
- <subsection name="Profile Selectors">
- <p>In preparation.</p>
+ <subsection name="Profile Selection">
+ <p>
+ In the <a href="profiles.html">Profile tutorial</a> we covered the
+ mechanisms used to establish a set of preconfigured deployment
+ profiles. Generally speaking the combination of profile overriding
+ in the block.xml <component> directive, packaged profiles,
+ and default configurations is sufficient. However, mechanisms are
+ provided for the introduction of profile selection policy. In this
+ tutorial we include multiple deployment profiles to the random
+ generator component and we define a custom profile selector. The
+ selector is declatred to Merlin as an attribute of the dependency
+ declared by the consuming component (HelloComponent).
+ </p>
+ <p>
+ Component deployment profiles are co-located with the component
+ implementation class under a .xprofile resource.
+ </p>
+ </subsection>
+ <subsection name="Adding multiple profiles">
+ <p>
+ The RandomGeneratorProvider.xprofile is updated to include
+ multiple profiles.
+ </p>
+ <p><i>RandomGeneratorProvider.xprofile</i></p>
+<source><![CDATA[
+<?xml version="1.0"?>
+
+<profiles>
+
+ <profile name="primary">
+ <configuration>
+ <seed>1024</seed>
+ </configuration>
+ </profile>
+
+ <profile name="secondary">
+ <configuration>
+ <seed>2048</seed>
+ </configuration>
+ </profile>
+
+</profiles>
+]]></source>
+ </subsection>
+ <subsection name="Creating a ProfileSelector">
+ <p>
+ A ProfileSelector may be declared to Merlin as part of a dependency
+ declaration. The following code is an implementation of a profile
+ selector.
+ </p>
+ <p><i>RandomProfileSelector.java</i></p>
+<source><![CDATA[
+package tutorial;
+
+import org.apache.avalon.assembly.engine.profile.ProfileSelector;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.meta.info.StageDescriptor;
+import org.apache.avalon.meta.info.DependencyDescriptor;
+import org.apache.avalon.meta.model.Profile;
+
+/**
+ * Select one profile from the multiple profile provided.
+ */
+public class RandomProfileSelector extends AbstractLogEnabled
+ implements ProfileSelector
+{
+
+ /**
+ * Returns the preferred profile form an available selection of
+ * candidate profiles.
+ * @param profiles the set of candidate profiles
+ * @param dependency the service dependency
+ * @return the preferred profile or null if no satisfactory provider can be
established
+ */
+ public Profile select( Profile[] profiles, DependencyDescriptor dependency )
+ {
+ if( profiles.length == 0 )
+ {
+ return null;
+ }
+
+ //
+ // just for fun log the available profiles
+ //
+
+ for( int i=0; i<profiles.length; i++ )
+ {
+ Profile profile = profiles[i];
+ getLogger().info( "available profile: " + profile.getName() );
+ }
+
+ //
+ // select the profile with the highest seed value
+ //
+
+ long seed = 0;
+ Profile selection = profiles[0];
+ for( int i=0; i<profiles.length; i++ )
+ {
+ Profile profile = profiles[i];
+ long value = profile.getConfiguration().getChild( "seed"
).getValueAsLong( 0 );
+ if( value > seed )
+ {
+ seed = value;
+ selection = profile;
+ }
+ }
+ return selection;
+ }
+
+ /**
+ * Returns the preferred profile form an available selection of
+ * candidate profiles.
+ * @param profiles the set of candidate profiles
+ * @param stage the service stage depedency
+ * @return the prefered profile or null if no satisfactory provider can be
established
+ */
+ public Profile select( Profile[] profiles, StageDescriptor stage )
+ {
+ return null;
+ }
+}
+]]></source>
+ </subsection>
+ <subsection name="Associating the selector with a dependency">
+ <p>
+ A custom selector is declared under the dependent component. This is
+ achieved by declaring the "urn:avalon:profile.selector" attribute
+ with a value corresponding to the classname of the selector.
+ </p>
+ <p><i>HelloComponent.xinfo</i></p>
+<source><![CDATA[
+<type>
+ <info>
+ <name>hello</name>
+ <version>1.0</version>
+ </info>
+ <dependencies>
+ <dependency key="random" type="tutorial.RandomGenerator">
+ <attributes>
+ <attribute key="urn:avalon:profile.selector"
value="tutorial.RandomProfileSelector"/>
+ </attributes>
+ </dependency>
+ </dependencies>
+</type>
+]]></source>
+ </subsection>
+ <subsection name="Executing the tutorial">
+ <p>
+ Build and run the tutorial.
+ </p>
+ <source>
+$ ant
+$ merlin build\classes
+ </source>
+ <p>
+ In the logging output we see that Merlin has selected the profile
+ with the highest seed value (the profile selection criteria implemented
+ by our custom selector).
+ </p>
+<source>
+[INFO ] (sys.profiles.selector): available profile: random-provider#primary
+[INFO ] (sys.profiles.selector): available profile: random-provider#secondary
+[INFO ] (tutorial.hello.random-provider#secondary): configuration stage
+[INFO ] (tutorial.hello.random-provider#secondary): seed: 2048
+[INFO ] (tutorial.hello): random: -1282354722
+</source>
</subsection>
</section>
</body>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]