/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.controller.transform.description; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.COMPOSITE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.STEPS; import java.util.Collections; import java.util.NoSuchElementException; import org.jboss.as.controller.ExpressionResolver; import org.jboss.as.controller.ModelVersion; import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathElement; import org.jboss.as.controller.ProcessType; import org.jboss.as.controller.ResourceDefinition; import org.jboss.as.controller.RunningMode; import org.jboss.as.controller.SimpleResourceDefinition; import org.jboss.as.controller.descriptions.ModelDescriptionConstants; import org.jboss.as.controller.descriptions.NonResolvingResourceDescriptionResolver; import org.jboss.as.controller.operations.common.Util; import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.controller.registry.Resource; import org.jboss.as.controller.transform.OperationResultTransformer; import org.jboss.as.controller.transform.OperationTransformer; import org.jboss.as.controller.transform.PathAddressTransformer; import org.jboss.as.controller.transform.ResourceTransformationContext; import org.jboss.as.controller.transform.ResourceTransformer; import org.jboss.as.controller.transform.TransformationContext; import org.jboss.as.controller.transform.TransformationTarget; import org.jboss.as.controller.transform.TransformationTargetImpl; import org.jboss.as.controller.transform.TransformerRegistry; import org.jboss.as.controller.transform.Transformers; import org.jboss.as.controller.transform.TransformersSubRegistration; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * @author Emanuel Muckenhuber */ public class BasicResourceTestCase { private static PathElement PATH = PathElement.pathElement("toto", "testSubsystem"); private static PathElement DISCARD = PathElement.pathElement("discard"); private static PathElement DYNAMIC = PathElement.pathElement("dynamic"); private static PathElement DYNAMIC_REDIRECT_ORIGINAL = PathElement.pathElement("dynamic-redirect-original"); private static PathElement DYNAMIC_REDIRECT_NEW = PathElement.pathElement("dynamic-redirect-new"); private static PathElement CONFIGURATION_TEST = PathElement.pathElement("configuration", "test"); private static PathElement TEST_CONFIGURATION = PathElement.pathElement("test", "configuration"); private static PathElement SETTING_DIRECTORY = PathElement.pathElement("setting", "directory"); private static PathElement DIRECTORY_SETTING = PathElement.pathElement("directory", "setting"); private Resource resourceRoot = Resource.Factory.create(); private TransformerRegistry registry = TransformerRegistry.Factory.create(); private ManagementResourceRegistration resourceRegistration = ManagementResourceRegistration.Factory.forProcessType(ProcessType.EMBEDDED_SERVER).createRegistration(ROOT); private static final TransformationDescription description; static { // Build final ResourceTransformationDescriptionBuilder builder = TransformationDescriptionBuilder.Factory.createInstance(PATH); builder.getAttributeBuilder() .addRejectCheck(RejectAttributeChecker.SIMPLE_EXPRESSIONS, "test") .setValueConverter(AttributeConverter.Factory.createHardCoded(new ModelNode(true)), "othertest") .end(); // Create a child resource based on an attribute final ResourceTransformationDescriptionBuilder attrResourceBuilder = builder.addChildResource(PathElement.pathElement("attribute-resource")) .getAttributeBuilder().addRejectCheck(RejectAttributeChecker.SIMPLE_EXPRESSIONS, "test-resource") .end() .setCustomResourceTransformer(new ResourceTransformer() { @Override public void transformResource(final ResourceTransformationContext context, final PathAddress address, final Resource resource) throws OperationFailedException { // Remote the test-resource attribute final ModelNode model = resource.getModel(); final ModelNode testResource = model.remove("test-resource"); // Add the current resource context.addTransformedResource(PathAddress.EMPTY_ADDRESS, resource); // Use the test-resource attribute to create a child final Resource child = Resource.Factory.create(); child.getModel().get("attribute").set(testResource); context.addTransformedResource(PathAddress.EMPTY_ADDRESS.append(PathElement.pathElement("resource", "test")), child); context.processChildren(resource); } }); attrResourceBuilder.addChildRedirection(PathElement.pathElement("resource-attribute"), new PathAddressTransformer() { @Override public PathAddress transform(PathElement current, Builder builder) { return builder.next(); // skip the current element } }) .getAttributeBuilder().addRejectCheck(RejectAttributeChecker.SIMPLE_EXPRESSIONS, "test-attribute").end() .setCustomResourceTransformer(new ResourceTransformer() { @Override public void transformResource(ResourceTransformationContext context, PathAddress address, Resource resource) throws OperationFailedException { // Get the current attribute final ModelNode attribute = resource.getModel().get("test-attribute"); // Add it to the existing resource final Resource existing = context.readTransformedResource(PathAddress.EMPTY_ADDRESS); // final ModelNode model = existing.getModel(); model.get("test-attribute").set(attribute); } }); builder.addOperationTransformationOverride("test-operation") .setValueConverter(AttributeConverter.Factory.createHardCoded(new ModelNode(true)), "operation-test") .inheritResourceAttributeDefinitions() .end(); builder.addOperationTransformationOverride("rename-operation") .rename("new-name-op") .setValueConverter(AttributeConverter.Factory.createHardCoded(new ModelNode(true)), "operation-test") .end(); builder.addOperationTransformationOverride("operation-with-transformer") .setCustomOperationTransformer(new OperationTransformer() { @Override public TransformedOperation transformOperation(TransformationContext context, PathAddress address, ModelNode operation) throws OperationFailedException { ModelNode remove = operation.clone(); remove.get(OP).set(REMOVE); remove.remove("test"); ModelNode add = operation.clone(); add.get(OP).set(ADD); add.get("new").set("shiny"); ModelNode composite = new ModelNode(); composite.get(OP).set(COMPOSITE); composite.get(OP_ADDR).setEmptyList(); composite.get(STEPS).add(remove); composite.get(STEPS).add(add); return new TransformedOperation(composite, OperationResultTransformer.ORIGINAL_RESULT); } }); // Discard all builder.discardChildResource(DISCARD); builder.addChildResource(DYNAMIC, new TestDynamicDiscardPolicy()) .getAttributeBuilder() .setValueConverter(new AttributeConverter.DefaultAttributeConverter() { @Override protected void convertAttribute(PathAddress address, String attributeName, ModelNode attributeValue, TransformationContext context) { attributeValue.set(attributeValue.asString().toUpperCase()); } }, "attribute"); builder.addChildRedirection(DYNAMIC_REDIRECT_ORIGINAL, DYNAMIC_REDIRECT_NEW, new TestDynamicDiscardPolicy()) .getAttributeBuilder() .setValueConverter(new AttributeConverter.DefaultAttributeConverter() { @Override protected void convertAttribute(PathAddress address, String attributeName, ModelNode attributeValue, TransformationContext context) { attributeValue.set(attributeValue.asString().toUpperCase()); } }, "attribute"); // configuration=test/setting=directory > test=configuration/directory=setting builder.addChildRedirection(CONFIGURATION_TEST, TEST_CONFIGURATION) .getAttributeBuilder().addRejectCheck(RejectAttributeChecker.SIMPLE_EXPRESSIONS, "test-config").end() .addChildRedirection(SETTING_DIRECTORY, DIRECTORY_SETTING); // Register at the server root description = builder.build(); } @Before public void setUp() { // Cleanup resourceRoot = Resource.Factory.create(); registry = TransformerRegistry.Factory.create(); resourceRegistration = ManagementResourceRegistration.Factory.forProcessType(ProcessType.EMBEDDED_SERVER).createRegistration(ROOT); // test final Resource toto = Resource.Factory.create(); toto.getModel().get("test").set("onetwothree"); // discard final Resource discard = Resource.Factory.create(); discard.getModel().get("attribute").set("two"); toto.registerChild(PathElement.pathElement("discard", "one"), discard); //dynamic discard final Resource dynamicKeep = Resource.Factory.create(); dynamicKeep.getModel().get("attribute").set("keep"); toto.registerChild(PathElement.pathElement("dynamic", "keep"), dynamicKeep); final Resource dynamicReject = Resource.Factory.create(); dynamicReject.getModel().get("attribute").set("reject"); toto.registerChild(PathElement.pathElement("dynamic", "reject"), dynamicReject); final Resource dynamicDiscard = Resource.Factory.create(); dynamicDiscard.getModel().get("attribute").set("discard"); toto.registerChild(PathElement.pathElement("dynamic", "discard"), dynamicDiscard); //dynamic discard and child redirection final Resource dynamicRedirectKeep = Resource.Factory.create(); dynamicRedirectKeep.getModel().get("attribute").set("keep"); toto.registerChild(PathElement.pathElement("dynamic-redirect-original", "keep"), dynamicRedirectKeep); final Resource dynamicRedirectReject = Resource.Factory.create(); dynamicRedirectReject.getModel().get("attribute").set("reject"); toto.registerChild(PathElement.pathElement("dynamic-redirect-original", "reject"), dynamicRedirectReject); final Resource dynamicRedirectDiscard = Resource.Factory.create(); dynamicRedirectDiscard.getModel().get("attribute").set("discard"); toto.registerChild(PathElement.pathElement("dynamic-redirect-original", "discard"), dynamicRedirectDiscard); // configuration final Resource configuration = Resource.Factory.create(); final Resource setting = Resource.Factory.create(); configuration.registerChild(SETTING_DIRECTORY, setting); toto.registerChild(CONFIGURATION_TEST, configuration); // attribute-resource final Resource attrResource = Resource.Factory.create(); attrResource.getModel().get("test-resource").set("abc"); toto.registerChild(PathElement.pathElement("attribute-resource", "test"), attrResource); // resource-attribute final Resource resourceAttr = Resource.Factory.create(); resourceAttr.getModel().get("test-attribute").set("test"); attrResource.registerChild(PathElement.pathElement("resource-attribute", "test"), resourceAttr); // resourceRoot.registerChild(PATH, toto); // Register the description final TransformersSubRegistration reg = registry.getServerRegistration(ModelVersion.create(1)); TransformationDescription.Tools.register(description, reg); } @Test public void testResourceTransformation() throws Exception { final ModelNode address = new ModelNode(); address.add("toto", "testSubsystem"); final ModelNode node = new ModelNode(); node.get(ModelDescriptionConstants.OP).set("add"); node.get(ModelDescriptionConstants.OP_ADDR).set(address); final OperationTransformer.TransformedOperation op = transformOperation(ModelVersion.create(1), node); Assert.assertNotNull(op); final Resource resource = transformResource(ModelVersion.create(1)); Assert.assertNotNull(resource); final Resource toto = resource.getChild(PATH); final ModelNode model = toto.getModel(); Assert.assertNotNull(toto); Assert.assertFalse(toto.hasChild(PathElement.pathElement("discard", "one"))); Assert.assertFalse(toto.hasChild(CONFIGURATION_TEST)); Assert.assertFalse(toto.hasChild(PathElement.pathElement("dynamic", "discard"))); Assert.assertFalse(toto.hasChild(PathElement.pathElement("dynamic", "reject"))); Resource dynamicKeep = toto.getChild(PathElement.pathElement("dynamic", "keep")); Assert.assertEquals("KEEP", dynamicKeep.getModel().get("attribute").asString()); Assert.assertFalse(toto.hasChildren("dynamic-redirect-original")); //Make sure that we didn't keep the originals Assert.assertFalse(toto.hasChild(PathElement.pathElement("dynamic-redirect-new", "discard"))); Assert.assertFalse(toto.hasChild(PathElement.pathElement("dynamic-redirect-new", "reject"))); Resource dynamicRedirectKeep = toto.getChild(PathElement.pathElement("dynamic-redirect-new", "keep")); Assert.assertEquals("KEEP", dynamicRedirectKeep.getModel().get("attribute").asString()); final Resource attResource = toto.getChild(PathElement.pathElement("attribute-resource", "test")); Assert.assertNotNull(attResource); final ModelNode attResourceModel = attResource.getModel(); Assert.assertFalse(attResourceModel.get("test-resource").isDefined()); // check that the resource got removed Assert.assertTrue(attResourceModel.hasDefined("test-attribute")); Assert.assertTrue(attResource.hasChild(PathElement.pathElement("resource", "test"))); } @Test public void testAddOperation() throws Exception { final ModelNode address = new ModelNode(); address.add("toto", "testSubsystem"); final ModelNode node = new ModelNode(); node.get(ModelDescriptionConstants.OP).set("add"); node.get(ModelDescriptionConstants.OP_ADDR).set(address); node.get("test").set("${one:two}"); OperationTransformer.TransformedOperation op = transformOperation(ModelVersion.create(1), node); Assert.assertTrue(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 1), node); Assert.assertTrue(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 5), node); Assert.assertTrue(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 1), node); Assert.assertFalse(op.rejectOperation(success())); node.get("test").set("concrete"); op = transformOperation(ModelVersion.create(1), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 1), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 5), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 1), node); Assert.assertFalse(op.rejectOperation(success())); } @Test public void testWriteAttribute() throws Exception { final ModelNode address = new ModelNode(); address.add("toto", "testSubsystem"); final ModelNode node = new ModelNode(); node.get(ModelDescriptionConstants.OP).set("write-attribute"); node.get(ModelDescriptionConstants.OP_ADDR).set(address); node.get("name").set("test"); node.get("value").set("${one:two}"); OperationTransformer.TransformedOperation op = transformOperation(ModelVersion.create(1), node); Assert.assertTrue(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 1), node); Assert.assertTrue(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 5), node); Assert.assertTrue(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 1), node); Assert.assertFalse(op.rejectOperation(success())); node.get("value").set("test"); op = transformOperation(ModelVersion.create(1), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 1), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 5), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 1), node); Assert.assertFalse(op.rejectOperation(success())); } @Test public void testAlias() throws Exception { final ModelNode address = new ModelNode(); address.add("toto", "testSubsystem"); address.add("configuration", "test"); final ModelNode node = new ModelNode(); node.get(ModelDescriptionConstants.OP).set("add"); node.get(ModelDescriptionConstants.OP_ADDR).set(address); node.get("test-config").set("${one:two}"); validateAliasTransformation(node.clone(), ModelVersion.create(1)); validateAliasTransformation(node.clone(), ModelVersion.create(1, 0, 1)); validateAliasTransformation(node.clone(), ModelVersion.create(1, 0, 5)); OperationTransformer.TransformedOperation op = transformOperation(ModelVersion.create(1, 1), node.clone()); Assert.assertFalse(op.rejectOperation(success())); node.get("test-config").set("concrete"); op = transformOperation(ModelVersion.create(1), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 1), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 0, 5), node); Assert.assertFalse(op.rejectOperation(success())); op = transformOperation(ModelVersion.create(1, 1), node); Assert.assertFalse(op.rejectOperation(success())); } private void validateAliasTransformation(final ModelNode node, final ModelVersion version) throws OperationFailedException, NoSuchElementException { OperationTransformer.TransformedOperation op = transformOperation(version, node); Assert.assertTrue(op.rejectOperation(success())); PathAddress transformed = PathAddress.pathAddress(op.getTransformedOperation().require(OP_ADDR)); Assert.assertEquals(transformed.getLastElement().getKey(), "test"); Assert.assertEquals(transformed.getLastElement().getValue(), "configuration"); } @Test public void testOperationOverride() throws Exception { final ModelNode address = new ModelNode(); address.add("toto", "testSubsystem"); final ModelNode operation = new ModelNode(); operation.get(ModelDescriptionConstants.OP).set("test-operation"); operation.get(ModelDescriptionConstants.OP_ADDR).set(address); operation.get("test").set("${one:two}"); validateOperationOverride(operation, ModelVersion.create(1)); validateOperationOverride(operation, ModelVersion.create(1, 0, 1)); validateOperationOverride(operation, ModelVersion.create(1, 0, 5)); OperationTransformer.TransformedOperation op = transformOperation(ModelVersion.create(1, 1), operation); Assert.assertFalse(op.rejectOperation(success())); // inherited } private void validateOperationOverride(final ModelNode operation, final ModelVersion version) throws IllegalArgumentException, OperationFailedException { OperationTransformer.TransformedOperation op = transformOperation(version, operation); ModelNode transformed = op.getTransformedOperation(); Assert.assertTrue(transformed.get("operation-test").asBoolean()); // explicit Assert.assertTrue(transformed.get("othertest").asBoolean()); // inherited Assert.assertTrue(op.rejectOperation(success())); // inherited } @Test public void testOperationTransformer() throws Exception { final ModelNode address = new ModelNode(); address.add("toto", "testSubsystem"); final ModelNode operation = new ModelNode(); operation.get(ModelDescriptionConstants.OP).set("operation-with-transformer"); operation.get(ModelDescriptionConstants.OP_ADDR).set(address); operation.get("test").set("a"); validateCompositeOperationTransformation(operation, ModelVersion.create(1)); validateCompositeOperationTransformation(operation, ModelVersion.create(1, 0 , 1)); validateCompositeOperationTransformation(operation, ModelVersion.create(1, 0 , 5)); } private void validateCompositeOperationTransformation(final ModelNode operation, final ModelVersion version) throws OperationFailedException { OperationTransformer.TransformedOperation op = transformOperation(version, operation); final ModelNode transformed = op.getTransformedOperation(); System.out.println(transformed); Assert.assertEquals(COMPOSITE, transformed.get(OP).asString()); Assert.assertEquals(new ModelNode().setEmptyList(), transformed.get(OP_ADDR)); Assert.assertEquals(ModelType.LIST, transformed.get(STEPS).getType()); Assert.assertEquals(2, transformed.get(STEPS).asList().size()); ModelNode remove = transformed.get(STEPS).asList().get(0); Assert.assertEquals(2, remove.keys().size()); Assert.assertEquals(REMOVE, remove.get(OP).asString()); Assert.assertEquals(PATH, PathAddress.pathAddress(remove.get(OP_ADDR)).iterator().next()); ModelNode add = transformed.get(STEPS).asList().get(1); Assert.assertEquals(4, add.keys().size()); Assert.assertEquals(ADD, add.get(OP).asString()); Assert.assertEquals(PATH, PathAddress.pathAddress(add.get(OP_ADDR)).iterator().next()); Assert.assertEquals("a", add.get("test").asString()); Assert.assertEquals("shiny", add.get("new").asString()); } @Test public void testRenameOperation() throws Exception { final ModelNode address = new ModelNode(); address.add("toto", "testSubsystem"); final ModelNode operation = new ModelNode(); operation.get(ModelDescriptionConstants.OP).set("rename-operation"); operation.get(ModelDescriptionConstants.OP_ADDR).set(address); operation.get("param").set("test"); validateRenamedOperation(operation, ModelVersion.create(1)); validateRenamedOperation(operation, ModelVersion.create(1, 0, 1)); validateRenamedOperation(operation, ModelVersion.create(1, 0, 5)); OperationTransformer.TransformedOperation op = transformOperation(ModelVersion.create(1, 1), operation); final ModelNode notTransformed = op.getTransformedOperation(); Assert.assertEquals("rename-operation", notTransformed.get(OP).asString()); } private void validateRenamedOperation(final ModelNode operation, final ModelVersion version) throws IllegalArgumentException, OperationFailedException { OperationTransformer.TransformedOperation op = transformOperation(version, operation); final ModelNode transformed = op.getTransformedOperation(); Assert.assertEquals("new-name-op", transformed.get(OP).asString()); Assert.assertEquals("test", transformed.get("param").asString()); Assert.assertTrue(transformed.get("operation-test").asBoolean()); // explicit Assert.assertFalse(transformed.hasDefined("othertest")); // not inherited Assert.assertFalse(op.rejectOperation(success())); // inherited } @Test public void testDynamicDiscardOperations() throws Exception { PathAddress subsystem = PathAddress.pathAddress("toto", "testSubsystem"); final PathAddress keepAddress = subsystem.append("dynamic", "keep"); final ModelNode opKeep = Util.createAddOperation(keepAddress); opKeep.get("attribute").set("keep"); OperationTransformer.TransformedOperation txKeep = transformOperation(ModelVersion.create(1), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("KEEP", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); txKeep = transformOperation(ModelVersion.create(1, 0, 1), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("KEEP", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); txKeep = transformOperation(ModelVersion.create(1, 0, 5), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("KEEP", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); txKeep = transformOperation(ModelVersion.create(1, 1), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("keep", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); final ModelNode opDiscard = Util.createAddOperation(subsystem.append("dynamic", "discard")); OperationTransformer.TransformedOperation txDiscard = transformOperation(ModelVersion.create(1), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNull(txDiscard.getTransformedOperation()); txDiscard = transformOperation(ModelVersion.create(1, 0, 1), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNull(txDiscard.getTransformedOperation()); txDiscard = transformOperation(ModelVersion.create(1, 0, 5), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNull(txDiscard.getTransformedOperation()); txDiscard = transformOperation(ModelVersion.create(1, 1), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNotNull(txDiscard.getTransformedOperation()); final ModelNode opReject = Util.createAddOperation(subsystem.append("dynamic", "reject")); OperationTransformer.TransformedOperation txReject = transformOperation(ModelVersion.create(1), opReject.clone()); Assert.assertTrue(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); txReject = transformOperation(ModelVersion.create(1, 0, 1), opReject.clone()); Assert.assertTrue(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); txReject = transformOperation(ModelVersion.create(1, 0, 5), opReject.clone()); Assert.assertTrue(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); txReject = transformOperation(ModelVersion.create(1, 1), opReject.clone()); Assert.assertFalse(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); } @Test public void testDynamicDiscardRedirectOperations() throws Exception { PathAddress subsystem = PathAddress.pathAddress("toto", "testSubsystem"); final PathAddress keepNewAddress = subsystem.append("dynamic-redirect-new", "keep"); final PathAddress keepOriginalAddress = subsystem.append("dynamic-redirect-original", "keep"); final ModelNode opKeep = Util.createAddOperation(keepOriginalAddress); opKeep.get("attribute").set("keep"); OperationTransformer.TransformedOperation txKeep = transformOperation(ModelVersion.create(1), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("KEEP", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepNewAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); txKeep = transformOperation(ModelVersion.create(1, 0, 1), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("KEEP", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepNewAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); txKeep = transformOperation(ModelVersion.create(1, 0, 5), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("KEEP", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepNewAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); txKeep = transformOperation(ModelVersion.create(1, 1), opKeep.clone()); Assert.assertFalse(txKeep.rejectOperation(success())); Assert.assertNotNull(txKeep.getTransformedOperation()); Assert.assertEquals("keep", txKeep.getTransformedOperation().get("attribute").asString()); Assert.assertEquals(keepOriginalAddress, PathAddress.pathAddress(txKeep.getTransformedOperation().get(OP_ADDR))); final ModelNode opDiscard = Util.createAddOperation(subsystem.append("dynamic-redirect-original", "discard")); OperationTransformer.TransformedOperation txDiscard = transformOperation(ModelVersion.create(1), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNull(txDiscard.getTransformedOperation()); txDiscard = transformOperation(ModelVersion.create(1, 0, 1), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNull(txDiscard.getTransformedOperation()); txDiscard = transformOperation(ModelVersion.create(1, 0, 5), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNull(txDiscard.getTransformedOperation()); txDiscard = transformOperation(ModelVersion.create(1, 1), opDiscard.clone()); Assert.assertFalse(txDiscard.rejectOperation(success())); Assert.assertNotNull(txDiscard.getTransformedOperation()); final ModelNode opReject = Util.createAddOperation(subsystem.append("dynamic-redirect-original", "reject")); OperationTransformer.TransformedOperation txReject = transformOperation(ModelVersion.create(1), opReject.clone()); Assert.assertTrue(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); txReject = transformOperation(ModelVersion.create(1, 0, 1), opReject.clone()); Assert.assertTrue(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); txReject = transformOperation(ModelVersion.create(1, 0, 5), opReject.clone()); Assert.assertTrue(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); txReject = transformOperation(ModelVersion.create(1, 1), opReject.clone()); Assert.assertFalse(txReject.rejectOperation(success())); Assert.assertNotNull(txReject.getTransformedOperation()); } private Resource transformResource(final ModelVersion version) throws OperationFailedException { final TransformationTarget target = create(registry, version); final ResourceTransformationContext context = createContext(target); return getTransfomers(target).transformResource(context, resourceRoot); } private OperationTransformer.TransformedOperation transformOperation(final ModelVersion version, final ModelNode operation) throws OperationFailedException { final TransformationTarget target = create(registry, version); final TransformationContext context = createContext(target); return getTransfomers(target).transformOperation(context, operation); } private ResourceTransformationContext createContext(final TransformationTarget target) { return Transformers.Factory.create(target, resourceRoot, resourceRegistration, ExpressionResolver.TEST_RESOLVER, RunningMode.NORMAL, ProcessType.STANDALONE_SERVER, null); } private Transformers getTransfomers(final TransformationTarget target) { return Transformers.Factory.create(target); } protected TransformationTarget create(final TransformerRegistry registry, ModelVersion version) { return create(registry, version, TransformationTarget.TransformationTargetType.SERVER); } protected TransformationTarget create(final TransformerRegistry registry, ModelVersion version, TransformationTarget.TransformationTargetType type) { return TransformationTargetImpl.create(null, registry, version, Collections.<PathAddress, ModelVersion>emptyMap(), type); } private static final ResourceDefinition ROOT = new SimpleResourceDefinition(PathElement.pathElement("test"), new NonResolvingResourceDescriptionResolver()); private static ModelNode success() { final ModelNode result = new ModelNode(); result.get(ModelDescriptionConstants.OUTCOME).set(ModelDescriptionConstants.SUCCESS); result.get(ModelDescriptionConstants.RESULT); return result; } private static class TestDynamicDiscardPolicy implements DynamicDiscardPolicy { @Override public DiscardPolicy checkResource(TransformationContext context, PathAddress address) { String action = address.getLastElement().getValue(); switch (action) { case "keep": return DiscardPolicy.NEVER; case "discard": return DiscardPolicy.DISCARD_AND_WARN; case "reject": return DiscardPolicy.REJECT_AND_WARN; } throw new IllegalArgumentException("Unknown address"); } } }