Advanced FeaturesProfile SelectionIn the Profile tutorial we covered the mechanisms used to establish a set of pre-configured 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 declared to Merlin as an attribute of the dependency declared by the consuming component (HelloComponent). Component deployment profiles are co-located with the component implementation class under an .xprofile resource. Adding multiple profilesThe RandomGeneratorProvider.xprofile is updated to include multiple profiles. RandomGeneratorProvider.xprofile <?xml version="1.0"?> <profiles> <profile name="primary"> <configuration> <seed>1024</seed> </configuration> </profile> <profile name="secondary"> <configuration> <seed>2048</seed> </configuration> </profile> </profiles> Creating a ProfileSelectorA ProfileSelector may be declared to Merlin as part of a dependency declaration. The following code is an implementation of a profile selector. RandomProfileSelector.java 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; } } Associating the selector with a dependencyA 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. HelloComponent.xinfo <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> Executing the tutorialBuild and run the tutorial. $ ant $ merlin build\classes 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). [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 |