JBoss Community Archive (Read Only)

WildFly 10

Transformers

This guide is work in progress

----

What are transformers

Transformers are mechanism used in domain mode, to support scenarios where you have host controllers (HC) joined to domain controller (DC) running different version of subsystem (server).

When HC registers itself against DC and it is running different version of some subsystem that is present on DC, DC performs transformation of model (ModelTransformer) and sends it back to HC as configuration it has too run.

Also when operations are performed on DC, for example call ADD for some resource, DC also transforms that operation (OperationTransformer) into target version of HC.

Transformers are primarily used for upgrade migration paths. General idea behind this migration period is that there are numerous HC and one DC deployed. First, DC is upgraded. Afterwards, HC are upgraded in steps as needed without breaking configuration.

When are they invoked

When Host controller registers to Domain Controller. HC does not know about conversions, they are done on DC as follows:

  1. HC -> connect -> DC

  2. HC <- list of subsystems to sent supported versions for <- DC

  3. HC -> list of supported versions for requested subsystems -> DC

  4. transformations happen on DC

  5. HC <- complete model in supported model versions <- DC

When should they be implemented

When model in your subsystem has changed in incompatible way.

Rule of thumb would be if current model is applied to previous version of subsystem model would it work? If not, model version must be increased and transformers implemented.

Model Transformer

Model transformer, works on top of current model and transforms its model to target version.

Operation Transformer

Operation transformer works on top of operations instead of model.

Testing transformers

There is testing framework in place for testing proper behavior of transformers. It is part of wildfly-subsystem-test-framework.

Simple transformers testing test

To create simple transformers test case you need to extend AbstractSubsystemBaseTest:

public class MyTransformersTestCase extends AbstractSubsystemBaseTest {
    public MyTransformersTestCase() {
        super("mysubsystem", new MySubsystemExtension());
    }
    @Override
    protected String getSubsystemXml() throws IOException {
        return readResource("testing.xml");
    }
}

Now you can add transformation test. The test will load a testing XML file into latest subsystem and will try to initialize legacy subsystem from it.

At first, lets specify target version of transformation. The frameworks requires to specify version of the controller using ModelTestControllerVersion enum and version of the model of the tested subsystem (ModelVersion as specified in the transformers). In following example we will transform to the subsystem model version default to the given controller version:

ModelTestControllerVersion controller = ModelTestControllerVersion.EAP_7_1_0;
ModelVersion subsystemModelVersion = controller.getSubsystemModelVersion("elytron");

The AbstractSubsystemBaseTest provides a method to obtain KernelServicesBuilder allowing to boot up controller for latest version of the subsystem:

KernelServicesBuilder builder = createKernelServicesBuilder(AdditionalInitialization.MANAGEMENT);

The builder will be used to boot up the old version of controller too. Take a note the old subsystem is downloaded from Maven repository:

builder.createLegacyKernelServicesBuilder(AdditionalInitialization.MANAGEMENT, controller, subsystemModelVersion)
       .addMavenResourceURL("org.wildfly.core:wildfly-elytron-integration:4.0.0.Final");

Now you can finish the builder and verify that both controllers has booted up successfully:

KernelServices services = builder.build();
assertTrue(services.isSuccessfulBoot());
assertTrue(services.getLegacyServices(subsystemModelVersion).isSuccessfulBoot());

The model parsed by latest controller from XML provided by{{getSubsystemXml()}} is now already transformed and used by the legacy controller. The framework provides method to check that both models are the same and valid:

checkSubsystemModelTransformation(services, subsystemModelVersion, null, true);

Testing of rejecting rules

Part of the transformers are also rejecting rules, which needs to be tested too. Lets image we have a new attribute "flushed" which cannot be part of the legacy model. To test it will be rejected, we need to write and XML configuration containing it, to parse it and to try to transform it:

List<ModelNode> operations = builder.parseXml(
    "<subsystem xmlns=\"urn:wildfly:mysubsystem:3.0\">\n" +
    "    <my-resource name=\"test\" flushed=\"true\"/>\n" +
    "</subsystem>");

ModelTestUtils.checkFailedTransformedBootOperations(services, subsystemModelVersion, operations, new FailedOperationTransformationConfig()
    .addFailedAttribute(myResourceTestPathAddress,
        new FailedOperationTransformationConfig.NewAttributesConfig("flushed"))
);

Util of testing subsystem will check that ALL listed attributes (and nothing else) was rejected.

Be aware the test framework use FailedOperationTransformationConfig to fix the model to continue checking following failures.
The NewAttributesConfig will ensure the attribute "flushed" will be undefined after its failing.
If you are checking rejecting subattribute in complex attribute, the whole attribute will be undefined, which will cause operation failure if the complex attribute was required. You need to use REJECTED_RESOURCE config in such case - the whole resource adding operation will be removed before continuing the evaluation.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:43:39 UTC, last content change 2018-05-17 11:52:23 UTC.