Migrator Definition Rules

Jesse Sightler edited this page Apr 9, 2014 · 29 revisions

To allow users to simply extend the coverage of migration without any compilation, migrators can be defined in a mix of XML definitions, JAXB 2.0 beans, Expression Language, and XSLT 2.0. See below for implementations used. For dev info, see External Migrator Execution.

##Example migrator definition

(taken from here)

    <?xml version="1.0" encoding="UTF-8"?>
    <migration>

        <migrator name="MailExtMigrator">

            <!-- Declare the JAXB classes. May also use Bean Validation and @Property annotations. -->
            <jaxbBean file="TestJaxbBean.groovy"/>

            <!-- Define a query of type XML, which returns a collection of JAXB beans.
                 Queries are performed during the `loadSourceServerConfig()` phase.
                 EL resolved in: pathMask, xpath, subjectLabel.
            -->
            <xmlQuery id="mailServices"
                pathMask="${srcServer.dir}/server/${srcServer.profile}/deploy/mail-service.xml"
                jaxbBean="TestJaxbBean"
                xpath="/server/mbean[@code='org.jboss.mail.MailService']"
                subjectLabel="Mail Service config"
            />

            <!-- Iterate over the results of the above query. 
                 For each iteration, the current item is accessible in EL as `${it}`. -->
            <forEach query="mailServices" var="it">
                <!-- Create an action of type CLI.
                     Actions are created during `prepareActions()` phase; then performed during `performActions()` phase.
                     EL resolved in: script.
                -->
                <action type="cli" var="addAction" script="/subsystem=mail/service=foo:add(name=bar,boo=baz)">
                    <!-- Only create the action for items which conform to this boolean Groovy expression. -->
                    <filter>
                        //! "smtp.nosuchhost.nosuchdomain.com".equals( it.getSmtpHost() )
                        it.getSmtpHost() != "smtp.nosuchhost.nosuchdomain.com"
                    </filter>
                    <!-- Define parameters for the CLI action.
                    <forEach query="...">
                        <param name="${...}" value="${...}"/>
                    </forEach>-->
                </action>
            </forEach>

            <!-- Example XSLT transformation of a file. -->
            <action type="xslt" var="addAction" pathMask="${srcServer.dir}/server/${srcServer.profile}/conf/cache-config.xml"
                xslt="JBossCache3_Infinispan4.xslt" dest="${destServer.configDir}">
            </action>

            <!-- Manual actions serve for noticing the user that some manual intervention after the migration is necessary.
                 Currently, mostly used by placeholder migrator implementations. -->
            <action type="manual">
                <warning>MailService beans migration is not yet supported.</warning>
                <forEach query="mailServices">
                    <filter>
                        //! "smtp.nosuchhost.nosuchdomain.com".equals( it.getSmtpHost() )
                        it.getSmtpHost() != "smtp.nosuchhost.nosuchdomain.com"
                    </filter>
                    <warning>  MailService will be skipped - JNDI name: ${it.getJndiName()}, MBean name: ${ms.getMbeanName()}</warning>
                </forEach>
            </action>

        </migrator>

    </migration>

EL expressions

What strings are resolved?

In general, those class properties which have the @EL annotation.
See the javadoc of implementations of ContainerOfstackableDefs.

Variables available in EL expressions

Built-in variables

  • ${mig} - instance of DefinitionBasedMigrator. You can reach most of everything you need from this root (as you can see in the following).
  • ${migDef} - shorthand for ${mig.descriptor}. See the MigratorDefinition javadoc.
  • ${migDefDir} - shorthand for ${mig.descriptor.origin.file.parentFile}. See the MigratorDefinition javadoc.
  • ${conf} - shorthand for ${mig.globalConfig}. See the GlobalConfig javadoc.
  • ${srcServer} - shorthand for ${mig.globalConfig.sourceServer}. Source server (e.g. JBoss EAP 5) config & info object. See AS5Config javadoc.
  • ${destServer} - target server (e.g. JBoss EAP 6) config & info object. See AS7Config javadoc.
  • ${workdir} - current directory as returned by new File(".") or userdir system property.

Variables available to the queries are currently limited to:

  • srcServer
  • destServer
  • migDefDir
    This limitation will be removed soon.

Action types and their configuration

There are several built-in actions, and additional can be used in a form of a Groovy class.

Built-in actions

EAP 6 specific actions:

  • CliCommandAction
  • ModuleCreationAction

File oriented actions:

  • CreateDirectoryAction
  • CopyAction
  • MergePropertiesFilesAction
  • XsltAction
    Default base directory for pathMask is (currently) CWD. Might change to ${srcServer.dir} in the future.

Special actions:

  • ManualAction

Description of actions is here.

Creating a custom action

A custom action is created by implementing IMigrationAction.

package org.jboss.loom.actions.ext;
...

/**
 *  My cool action.
 */
public class CoolAction implements IMigrationAction {
    private static final Logger log = LoggerFactory.getLogger( XsltAction.class );

    ...
}// class

An abstract implementation is available - AbstractStatefulAction - which implements default behavior for several features:

// Migration context, almost mandatory, it's a communication point with the rest of the app.
private MigrationContext ctx;

// Text message about where a particular action came from - what is it migrating etc.
private String originMessage;

// Can hold a stack trace of the place it was created. Useful for development.
private StackTraceElement originStacktrace;

// Which migrator (class) created this action.
private Class<? extends IMigrator> fromMigrator;

// Warnings to be displaed to the user in UI (console) and the XML and HTML reports.
private List<String> warnings = new LinkedList();

// List of action this action depends on. Used for sorting of actions when executing.
private List<IMigrationAction> deps = new LinkedList();

After creating an action, JAXB bean is needed, and also an implementation of IActionDefHandler.

Currently, action handling is hard-coded and only creates the built-in actions.
Later, implementations of IActionDefHandler interface will define new actions.

Implementations used

For your reference of features available, here are the implementations used in WindRide 0.11:

  • XML definitions: Handled by custom processor. See below for syntax.
  • JAXB 2.0 beans: Written in Groovy 2.1, handled by EclipseLink MOXy 2.5
    • Allows you to read XML or JSON configuration directly into a Java object of simply annotated class.
    • May use Bean Validation.
    • May describe their properties using [[@org.jboss.loom.spi.Property|Describing JAXB Beans Properties]].
  • Expression Language: Handled by JUEL 2.2
    • Allows you to refer to the parts of read configuration using EL, e.g. ${datasources[0].connection.userName}.
  • XSLT 2.0: Handled by Saxon 9.5.
    • Allows you to transform source server XML config files into target server's config files using XSLT templates.