/* * JBoss, Home of Professional Open Source. * Copyright 2006, Red Hat Middleware LLC, 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.test; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ATTRIBUTES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ATTRIBUTE_VALUE_WRITTEN_NOTIFICATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CHILDREN; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CHILD_TYPE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILED; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILURE_DESCRIPTION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MIN_LENGTH; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MODEL_DESCRIPTION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NILLABLE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NOTIFICATIONS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NOTIFICATION_TYPE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATIONS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_NAME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PROFILE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PROXIES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_ATTRIBUTE_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_CHILDREN_NAMES_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_CHILDREN_TYPES_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_OPERATION_DESCRIPTION_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_OPERATION_NAMES_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_RESOURCE_DESCRIPTION_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_RESOURCE_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RECURSIVE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REPLY_PROPERTIES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUEST_PROPERTIES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESOURCE_ADDED_NOTIFICATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESOURCE_REMOVED_NOTIFICATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESULT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALIDATE_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.WRITE_ATTRIBUTE_OPERATION; import static org.jboss.as.controller.test.TestUtils.createAttribute; import static org.jboss.as.controller.test.TestUtils.createMetric; import static org.jboss.as.controller.test.TestUtils.createOperationDefinition; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.ControlledProcessState; import org.jboss.as.controller.ManagementModel; import org.jboss.as.controller.ModelController; import org.jboss.as.controller.ModelOnlyWriteAttributeHandler; import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.OperationStepHandler; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathElement; import org.jboss.as.controller.ProcessType; import org.jboss.as.controller.ProxyController; import org.jboss.as.controller.ResourceBuilder; import org.jboss.as.controller.SimpleResourceDefinition; import org.jboss.as.controller.TestModelControllerService; import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.as.controller.client.Operation; import org.jboss.as.controller.client.OperationBuilder; import org.jboss.as.controller.descriptions.NonResolvingResourceDescriptionResolver; import org.jboss.as.controller.operations.common.ValidateOperationHandler; import org.jboss.as.controller.operations.global.GlobalNotifications; import org.jboss.as.controller.operations.global.GlobalOperationHandlers; import org.jboss.as.controller.persistence.NullConfigurationPersister; import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.as.controller.registry.Resource; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceContainer; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceTarget; import org.jboss.msc.value.InjectedValue; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Base class for tests of invocations from a main controller to a remote proxied controller. * * @author <a href="kabir.khan@jboss.com">Kabir Khan</a> */ public abstract class AbstractProxyControllerTest { private ExecutorService executor; private ModelControllerClient mainControllerClient; private ModelControllerClient proxiedControllerClient; private ServiceContainer container; @Before public void setupController() throws Exception { executor = Executors.newCachedThreadPool(); container = ServiceContainer.Factory.create("test"); ServiceTarget target = container.subTarget(); ControlledProcessState processState = new ControlledProcessState(true); ProxyModelControllerService proxyService = new ProxyModelControllerService(processState); ServiceBuilder<ModelController> proxyBuilder = target.addService(ServiceName.of("ProxyModelController"), proxyService); proxyBuilder.install(); MainModelControllerService mainService = new MainModelControllerService(processState); ServiceBuilder<ModelController> mainBuilder = target.addService(ServiceName.of("MainModelController"), mainService); mainBuilder.addDependency(ServiceName.of("ProxyModelController"), ModelController.class, mainService.proxy); mainBuilder.install(); proxyService.awaitStartup(30, TimeUnit.SECONDS); mainService.awaitStartup(30, TimeUnit.SECONDS); // execute operation to initialize the controller model final ModelNode operation = new ModelNode(); operation.get(OP).set("setup"); operation.get(OP_ADDR).setEmptyList(); mainControllerClient = mainService.getValue().createClient(executor); mainControllerClient.execute(operation); proxiedControllerClient = proxyService.getValue().createClient(executor); proxiedControllerClient.execute(operation); } @After public void shutdownServiceContainer() { if (container != null) { container.shutdown(); try { container.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } finally { container = null; } } executor.shutdownNow(); mainControllerClient = null; proxiedControllerClient = null; } @Test public void testRecursiveReadResourceDescriptionOperation() throws Exception { Operation operation = createOperation(READ_RESOURCE_DESCRIPTION_OPERATION); operation.getOperation().get(PROXIES).set(true); operation.getOperation().get(RECURSIVE).set(true); ModelNode result = proxiedControllerClient.execute(operation); checkHostSubModelDescription(result.get(RESULT), false, false); result = mainControllerClient.execute(operation); checkRootSubModelDescription(result.get(RESULT), false, false); result = mainControllerClient.execute(operation); checkRootSubModelDescription(result.get(RESULT), false, false); } @Test public void testRecursiveReadResourceDescriptionOperationForAddressInOtherController() throws Exception { Operation operation = createOperation(READ_RESOURCE_DESCRIPTION_OPERATION, SERVER, "serverA"); operation.getOperation().get(RECURSIVE).set(true); ModelNode result = mainControllerClient.execute(operation); checkHostSubModelDescription(result.get(RESULT), false, false); result = mainControllerClient.execute(operation); checkHostSubModelDescription(result.get(RESULT), false, false); } @Test public void testRecursiveReadResourceDescriptionWithOperations() throws Exception { Operation operation = createOperation(READ_RESOURCE_DESCRIPTION_OPERATION); operation.getOperation().get(PROXIES).set(true); operation.getOperation().get(RECURSIVE).set(true); operation.getOperation().get(OPERATIONS).set(true); ModelNode result = mainControllerClient.execute(operation); checkRootSubModelDescription(result.get(RESULT), true, false); } @Test public void testRecursiveReadResourceDescriptionWitNotifications() throws Exception { Operation operation = createOperation(READ_RESOURCE_DESCRIPTION_OPERATION); operation.getOperation().get(PROXIES).set(true); operation.getOperation().get(RECURSIVE).set(true); operation.getOperation().get(NOTIFICATIONS).set(true); ModelNode result = mainControllerClient.execute(operation); checkRootSubModelDescription(result.get(RESULT), false, true); } @Test public void testRecursiveReadSubModelOperation() throws Exception { Operation operation = createOperation(READ_RESOURCE_OPERATION); operation.getOperation().get(PROXIES).set(true); operation.getOperation().get(RECURSIVE).set(true); ModelNode result = proxiedControllerClient.execute(operation); checkHostNode(result.get(RESULT)); result = mainControllerClient.execute(operation); checkRootNode(result.get(RESULT)); } @Test public void testRecursiveReadSubModelOperationForAddressInOtherController() throws Exception { Operation operation = createOperation(READ_RESOURCE_OPERATION, SERVER, "serverA"); operation.getOperation().get(RECURSIVE).set(true); ModelNode result = mainControllerClient.execute(operation); checkHostNode(result.get(RESULT)); } @Test public void testWriteAttributeOperation() throws Exception { Operation write = createOperation(WRITE_ATTRIBUTE_OPERATION, "serverchild", "svrA", "child", "childA"); write.getOperation().get(NAME).set("value"); write.getOperation().get(VALUE).set("NewValue"); proxiedControllerClient.execute(write); Operation read = createOperation(READ_RESOURCE_OPERATION, "serverchild", "svrA", "child", "childA"); read.getOperation().get(RECURSIVE).set(true); ModelNode result = proxiedControllerClient.execute(read); assertEquals("NewValue", result.get(RESULT, "value").asString()); read = createOperation(READ_RESOURCE_OPERATION, SERVER, "serverA", "serverchild", "svrA", "child", "childA"); read.getOperation().get(RECURSIVE).set(true); result = mainControllerClient.execute(read); assertEquals("NewValue", result.get(RESULT, "value").asString()); } @Test public void testWriteAttributeOperationInChildController() throws Exception { Operation write = createOperation(WRITE_ATTRIBUTE_OPERATION, SERVER, "serverA", "serverchild", "svrA", "child", "childA"); write.getOperation().get(NAME).set("value"); write.getOperation().get(VALUE).set("NewValue2"); ModelNode result = mainControllerClient.execute(write); Operation read = createOperation(READ_RESOURCE_OPERATION, "serverchild", "svrA", "child", "childA"); read.getOperation().get(RECURSIVE).set(true); result = proxiedControllerClient.execute(read); assertEquals("NewValue2", result.get(RESULT, "value").asString()); read = createOperation(READ_RESOURCE_OPERATION, SERVER, "serverA", "serverchild", "svrA", "child", "childA"); read.getOperation().get(RECURSIVE).set(true); result = mainControllerClient.execute(read); assertEquals("NewValue2", result.get(RESULT, "value").asString()); } @Test public void testWriteAttributeOperationSanity() throws Exception { Operation write = createOperation(WRITE_ATTRIBUTE_OPERATION, "serverchild", "svrA", "child", "childA"); write.getOperation().get(NAME).set("value"); write.getOperation().get(VALUE).set("NewValue2"); ModelNode result = proxiedControllerClient.execute(write); Operation read = createOperation(READ_RESOURCE_OPERATION, "serverchild", "svrA", "child", "childA"); read.getOperation().get(RECURSIVE).set(true); result = proxiedControllerClient.execute(read); assertEquals("NewValue2", result.get(RESULT, "value").asString()); } @Test public void testReadAttributeOperationInChildController() throws Exception { Operation read = createOperation(READ_ATTRIBUTE_OPERATION, "serverchild", "svrA", "child", "childA"); read.getOperation().get(NAME).set("name"); ModelNode result = proxiedControllerClient.execute(read); assertEquals("childName", result.get(RESULT).asString()); read.getOperation().get(NAME).set("metric"); result = proxiedControllerClient.execute(read); assertEquals(ModelType.INT, result.get(RESULT).getType()); } @Test public void testReadOperationNames() throws Exception { Operation read = createOperation(READ_OPERATION_NAMES_OPERATION); ModelNode result = mainControllerClient.execute(read); checkOperationNames(result.get(RESULT), 22); read = createOperation(READ_OPERATION_NAMES_OPERATION, SERVER, "serverA"); result = mainControllerClient.execute(read); checkOperationNames(result.get(RESULT), 23); read = createOperation(READ_OPERATION_NAMES_OPERATION, SERVER, "serverA", "serverchild", "svrA"); result = mainControllerClient.execute(read); checkOperationNames(result.get(RESULT), 22); } @Test public void testReadOperationDescription() throws Exception { Operation read = createOperation(READ_OPERATION_DESCRIPTION_OPERATION); read.getOperation().get(NAME).set(READ_ATTRIBUTE_OPERATION); ModelNode result = mainControllerClient.execute(read); checkReadAttributeOperationDescription(result.get(RESULT)); read = createOperation(READ_OPERATION_DESCRIPTION_OPERATION, SERVER, "serverA"); read.getOperation().get(NAME).set(READ_ATTRIBUTE_OPERATION); result = mainControllerClient.execute(read); checkReadAttributeOperationDescription(result.get(RESULT)); read = createOperation(READ_OPERATION_DESCRIPTION_OPERATION, SERVER, "serverA", "serverchild", "svrA"); read.getOperation().get(NAME).set(READ_ATTRIBUTE_OPERATION); result = mainControllerClient.execute(read); checkReadAttributeOperationDescription(result.get(RESULT)); } @Test public void testReadChildNames() throws Exception { Operation read = createOperation(READ_CHILDREN_NAMES_OPERATION); read.getOperation().get(CHILD_TYPE).set(SERVER); ModelNode result = mainControllerClient.execute(read).get(RESULT); assertNotNull(result); assertEquals(ModelType.LIST, result.getType()); assertEquals(1, result.asList().size()); assertEquals("serverA", result.get(0).asString()); read = createOperation(READ_CHILDREN_NAMES_OPERATION, SERVER, "serverA"); read.getOperation().get(CHILD_TYPE).set("serverchild"); result = mainControllerClient.execute(read).get(RESULT); assertNotNull(result); assertEquals(ModelType.LIST, result.getType()); assertEquals(1, result.asList().size()); assertEquals("svrA", result.get(0).asString()); read = createOperation(READ_CHILDREN_NAMES_OPERATION, SERVER, "serverA", "serverchild", "svrA"); read.getOperation().get(CHILD_TYPE).set("child"); result = mainControllerClient.execute(read).get(RESULT); assertNotNull(result); assertEquals(ModelType.LIST, result.getType()); assertEquals(1, result.asList().size()); assertEquals("childA", result.get(0).asString()); } @Test public void testReadChildTypes() throws Exception { Operation read = createOperation(READ_CHILDREN_TYPES_OPERATION); ModelNode result = mainControllerClient.execute(read).get(RESULT); assertNotNull(result); assertEquals(ModelType.LIST, result.getType()); List<ModelNode> nodes = result.asList(); assertEquals(2, nodes.size()); List<String> typeNames = Arrays.asList(nodes.get(0).asString(), nodes.get(1).asString()); assertTrue(Arrays.asList(SERVER, "profile").containsAll(typeNames)); read = createOperation(READ_CHILDREN_TYPES_OPERATION, SERVER, "serverA"); assertNotNull(result); assertEquals(ModelType.LIST, result.getType()); nodes = result.asList(); assertEquals(2, nodes.size()); typeNames = Arrays.asList(nodes.get(0).asString(), nodes.get(1).asString()); assertTrue(Arrays.asList(SERVER, "profile").containsAll(typeNames)); read = createOperation(READ_CHILDREN_TYPES_OPERATION, SERVER, "serverA", "serverchild", "svrA"); result = mainControllerClient.execute(read).get(RESULT); assertNotNull(result); assertEquals(ModelType.LIST, result.getType()); nodes = result.asList(); assertEquals(1, nodes.size()); assertEquals("child", nodes.get(0).asString()); } @Test public void testValidateOperationOp() throws Exception { ModelNode candidate = createOperation(READ_CHILDREN_TYPES_OPERATION).getOperation(); Operation validate = createOperation(VALIDATE_OPERATION); validate.getOperation().get(VALUE).set(candidate); ModelNode result = mainControllerClient.execute(validate); Assert.assertFalse(result.get(FAILURE_DESCRIPTION).asString(), result.hasDefined(FAILURE_DESCRIPTION)); candidate = createOperation(READ_OPERATION_DESCRIPTION_OPERATION).getOperation(); candidate.get(NAME).set("Does not matter"); validate.getOperation().get(VALUE).set(candidate); result = mainControllerClient.execute(validate); Assert.assertFalse(result.get(FAILURE_DESCRIPTION).asString(), result.hasDefined(FAILURE_DESCRIPTION)); candidate = createOperation(READ_OPERATION_DESCRIPTION_OPERATION).getOperation(); candidate.get("Bad").set("Crap"); validate.getOperation().get(VALUE).set(candidate); result = mainControllerClient.execute(validate); Assert.assertEquals(FAILED, result.get(OUTCOME).asString()); candidate = createOperation(READ_CHILDREN_TYPES_OPERATION, SERVER, "serverA", "serverchild", "svrA").getOperation(); validate.getOperation().get(VALUE).set(candidate); result = mainControllerClient.execute(validate); Assert.assertFalse(result.get(FAILURE_DESCRIPTION).asString(), result.hasDefined(FAILURE_DESCRIPTION)); candidate = createOperation(READ_OPERATION_DESCRIPTION_OPERATION, SERVER, "serverA", "serverchild", "svrA").getOperation(); candidate.get(NAME).set("Does not matter"); validate.getOperation().get(VALUE).set(candidate); result = mainControllerClient.execute(validate); Assert.assertFalse(result.get(FAILURE_DESCRIPTION).asString(), result.hasDefined(FAILURE_DESCRIPTION)); candidate = createOperation(READ_CHILDREN_TYPES_OPERATION, SERVER, "serverA", "serverchild", "svrA").getOperation(); candidate.get("Bad").set("Crap"); validate.getOperation().get(VALUE).set(candidate); result = mainControllerClient.execute(validate); Assert.assertEquals(FAILED, result.get(OUTCOME).asString()); } private void checkReadAttributeOperationDescription(ModelNode result) { assertEquals(READ_ATTRIBUTE_OPERATION, result.get(OPERATION_NAME).asString()); assertEquals(ModelType.STRING, result.require(REQUEST_PROPERTIES).require(NAME).require(TYPE).asType()); assertEquals(ModelType.OBJECT, result.require(REPLY_PROPERTIES).require(TYPE).asType()); } private void checkOperationNames(ModelNode operationNamesList, int size) { assertTrue(operationNamesList.isDefined()); assertEquals(ModelType.LIST, operationNamesList.getType()); assertEquals(size, operationNamesList.asList().size()); } private void checkRootSubModelDescription(ModelNode result, boolean operations, boolean notifications) { assertEquals("description", result.get(DESCRIPTION).asString()); assertEquals("server", result.get(CHILDREN, SERVER, DESCRIPTION).asString()); assertEquals(1, result.get(CHILDREN, SERVER, MODEL_DESCRIPTION).keys().size()); assertEquals("profile", result.get(CHILDREN, PROFILE, DESCRIPTION).asString()); assertEquals(1, result.get(CHILDREN, PROFILE, MODEL_DESCRIPTION).keys().size()); if (operations) { Set<String> ops = result.require(OPERATIONS).keys(); assertTrue(ops.contains(READ_ATTRIBUTE_OPERATION)); assertTrue(ops.contains(READ_CHILDREN_NAMES_OPERATION)); assertTrue(ops.contains(READ_CHILDREN_TYPES_OPERATION)); assertTrue(ops.contains(READ_OPERATION_DESCRIPTION_OPERATION)); assertTrue(ops.contains(READ_OPERATION_NAMES_OPERATION)); assertTrue(ops.contains(READ_RESOURCE_DESCRIPTION_OPERATION)); assertTrue(ops.contains(READ_RESOURCE_OPERATION)); assertTrue(ops.contains(WRITE_ATTRIBUTE_OPERATION)); for (String op : ops) { assertEquals(op, result.require(OPERATIONS).require(op).require(OPERATION_NAME).asString()); } } if (notifications) { Set<String> notifs = result.require(NOTIFICATIONS).keys(); assertTrue(notifs.contains(RESOURCE_ADDED_NOTIFICATION)); assertTrue(notifs.contains(RESOURCE_REMOVED_NOTIFICATION)); assertTrue(notifs.contains(ATTRIBUTE_VALUE_WRITTEN_NOTIFICATION)); for (String notif : notifs) { assertEquals(notif, result.require(NOTIFICATIONS).require(notif).require(NOTIFICATION_TYPE).asString()); } } ModelNode proxy = result.get(CHILDREN, SERVER, MODEL_DESCRIPTION, "serverA"); checkHostSubModelDescription(proxy, operations, notifications); } private void checkHostSubModelDescription(ModelNode result, boolean operations, boolean notifications) { assertEquals(result.toString(), 6, result.keys().size()); assertEquals("description", result.get(DESCRIPTION).asString()); assertEquals("serverchild", result.get(CHILDREN, "serverchild", DESCRIPTION).asString()); assertEquals(1, result.get(CHILDREN, "serverchild", MODEL_DESCRIPTION).keys().size()); if (operations) { Set<String> ops = result.require(OPERATIONS).keys(); assertTrue(ops.contains(READ_ATTRIBUTE_OPERATION)); assertTrue(ops.contains(READ_CHILDREN_NAMES_OPERATION)); assertTrue(ops.contains(READ_CHILDREN_TYPES_OPERATION)); assertTrue(ops.contains(READ_OPERATION_DESCRIPTION_OPERATION)); assertTrue(ops.contains(READ_OPERATION_NAMES_OPERATION)); assertTrue(ops.contains(READ_RESOURCE_DESCRIPTION_OPERATION)); assertTrue(ops.contains(READ_RESOURCE_OPERATION)); assertTrue(ops.contains(WRITE_ATTRIBUTE_OPERATION)); for (String op : ops) { assertEquals(op, result.require(OPERATIONS).require(op).require(OPERATION_NAME).asString()); } } if (notifications) { Set<String> notifs = result.require(NOTIFICATIONS).keys(); assertTrue(notifs.contains(RESOURCE_ADDED_NOTIFICATION)); assertTrue(notifs.contains(RESOURCE_REMOVED_NOTIFICATION)); assertTrue(notifs.contains(ATTRIBUTE_VALUE_WRITTEN_NOTIFICATION)); for (String notif : notifs) { assertEquals(notif, result.require(NOTIFICATIONS).require(notif).require(NOTIFICATION_TYPE).asString()); } } checkHostChildSubModelDescription(result.get(CHILDREN, "serverchild", MODEL_DESCRIPTION, "*"), operations, notifications); } private void checkHostChildSubModelDescription(ModelNode result, boolean operations, boolean notifications) { assertEquals(5, result.keys().size()); assertEquals(1, result.get(ATTRIBUTES).keys().size()); assertEquals(ModelType.STRING, result.get(ATTRIBUTES, "name", TYPE).asType()); assertEquals("name", result.get(ATTRIBUTES, "name", DESCRIPTION).asString()); assertFalse(result.get(ATTRIBUTES, "name", NILLABLE).asBoolean()); assertEquals(1, result.get(ATTRIBUTES, "name", MIN_LENGTH).asInt()); assertEquals(1, result.get(CHILDREN).keys().size()); assertEquals("child", result.get(CHILDREN, "child", DESCRIPTION).asString()); //we don't fully support this atm //assertEquals(1, result.get(CHILDREN, "child", MIN_OCCURS).asInt()); assertEquals(1, result.get(CHILDREN, "child", MODEL_DESCRIPTION).keys().size()); if (operations) { Set<String> ops = result.require(OPERATIONS).keys(); assertTrue(ops.contains(READ_ATTRIBUTE_OPERATION)); assertTrue(ops.contains(READ_CHILDREN_NAMES_OPERATION)); assertTrue(ops.contains(READ_CHILDREN_TYPES_OPERATION)); assertTrue(ops.contains(READ_OPERATION_DESCRIPTION_OPERATION)); assertTrue(ops.contains(READ_OPERATION_NAMES_OPERATION)); assertTrue(ops.contains(READ_RESOURCE_DESCRIPTION_OPERATION)); assertTrue(ops.contains(READ_RESOURCE_OPERATION)); assertTrue(ops.contains(WRITE_ATTRIBUTE_OPERATION)); for (String op : ops) { assertEquals(op, result.require(OPERATIONS).require(op).require(OPERATION_NAME).asString()); } } if (notifications) { Set<String> notifs = result.require(NOTIFICATIONS).keys(); for (String notif : notifs) { assertEquals(notif, result.require(NOTIFICATIONS).require(notif).require(NOTIFICATION_TYPE).asString()); } assertTrue(notifs.contains(RESOURCE_ADDED_NOTIFICATION)); assertTrue(notifs.contains(RESOURCE_REMOVED_NOTIFICATION)); assertTrue(notifs.contains(ATTRIBUTE_VALUE_WRITTEN_NOTIFICATION)); } checkHostChildChildSubModelDescription(result.get(CHILDREN, "child", MODEL_DESCRIPTION, "*"), operations, notifications); } private void checkHostChildChildSubModelDescription(ModelNode result, boolean operations, boolean notifications) { assertEquals(5, result.keys().size()); assertEquals(3, result.get(ATTRIBUTES).keys().size()); assertEquals(ModelType.STRING, result.get(ATTRIBUTES, "name", TYPE).asType()); assertEquals("name", result.get(ATTRIBUTES, "name", DESCRIPTION).asString()); assertFalse(result.get(ATTRIBUTES, "name", NILLABLE).asBoolean()); assertEquals(1, result.get(ATTRIBUTES, "name", MIN_LENGTH).asInt()); assertEquals(ModelType.STRING, result.get(ATTRIBUTES, "value", TYPE).asType()); assertEquals("value", result.get(ATTRIBUTES, "value", DESCRIPTION).asString()); assertFalse(result.get(ATTRIBUTES, "value", NILLABLE).asBoolean()); assertEquals(1, result.get(ATTRIBUTES, "value", MIN_LENGTH).asInt()); if (!operations) { assertFalse(result.hasDefined(OPERATIONS)); } else { Set<String> ops = result.require(OPERATIONS).keys(); assertTrue(ops.contains("test-op")); for (String op : ops) { assertEquals(op, result.require(OPERATIONS).require(op).require(OPERATION_NAME).asString()); } } if (!notifications) { assertFalse(result.hasDefined(NOTIFICATIONS)); } else { Set<String> notifs = result.require(NOTIFICATIONS).keys(); assertTrue(notifs.contains(RESOURCE_ADDED_NOTIFICATION)); assertTrue(notifs.contains(RESOURCE_REMOVED_NOTIFICATION)); assertTrue(notifs.contains(ATTRIBUTE_VALUE_WRITTEN_NOTIFICATION)); for (String notif : notifs) { assertEquals(notif, result.require(NOTIFICATIONS).require(notif).require(NOTIFICATION_TYPE).asString()); } } } private void checkRootNode(ModelNode result) { assertEquals(2, result.keys().size()); assertEquals(1, result.get(SERVER).keys().size()); checkHostNode(result.get(SERVER, "serverA")); assertEquals(1, result.get("profile").keys().size()); assertEquals("Profile A", result.get("profile", "profileA", NAME).asString()); } private void checkHostNode(ModelNode result) { assertEquals(1, result.keys().size()); assertEquals("serverA", result.require("serverchild").require("svrA").require("name").asString()); assertEquals("childName", result.get("serverchild", "svrA", "child", "childA", "name").asString()); assertEquals("childValue", result.get("serverchild", "svrA", "child", "childA", "value").asString()); } private Operation createOperation(String operationName, String... address) { ModelNode operation = new ModelNode(); operation.get(OP).set(operationName); if (address.length > 0) { for (String addr : address) { operation.get(ADDRESS).add(addr); } } else { operation.get(ADDRESS).setEmptyList(); } return new OperationBuilder(operation).build(); } protected abstract ProxyController createProxyController(ModelController proxiedController, PathAddress proxyNodeAddress); public class MainModelControllerService extends TestModelControllerService { private final InjectedValue<ModelController> proxy = new InjectedValue<ModelController>(); MainModelControllerService(final ControlledProcessState processState) { super(ProcessType.EMBEDDED_SERVER, new NullConfigurationPersister(), processState, ResourceBuilder.Factory.create(PathElement.pathElement("root"), new NonResolvingResourceDescriptionResolver()).build()); } protected void initModel(ManagementModel managementModel, Resource modelControllerResource) { ManagementResourceRegistration rootRegistration = managementModel.getRootResourceRegistration(); GlobalOperationHandlers.registerGlobalOperations(rootRegistration, processType); GlobalNotifications.registerGlobalNotifications(rootRegistration, processType); rootRegistration.registerOperationHandler(ValidateOperationHandler.DEFINITION, ValidateOperationHandler.INSTANCE); rootRegistration.registerOperationHandler(TestUtils.SETUP_OPERATION_DEF, new OperationStepHandler() { @Override public void execute(OperationContext context, ModelNode operation) throws OperationFailedException { ModelNode mainModel = new ModelNode(); mainModel.get(SERVER, "serverA"); //Create an empty node to be got from the proxied model mainModel.get("profile", "profileA").get(NAME).set("Profile A"); AbstractControllerTestBase.createModel(context, mainModel); } }); rootRegistration.registerSubModel(ResourceBuilder.Factory.create(PathElement.pathElement("profile", "*"), new NonResolvingResourceDescriptionResolver()) .addReadOnlyAttribute(TestUtils.createNillableAttribute("name",ModelType.STRING)) .build()); PathElement serverAElement = PathElement.pathElement(SERVER, "serverA"); rootRegistration.registerProxyController(serverAElement, createProxyController(proxy.getValue(), PathAddress.pathAddress(serverAElement))); } } public class ProxyModelControllerService extends TestModelControllerService { ProxyModelControllerService(final ControlledProcessState processState) { super(ProcessType.EMBEDDED_SERVER, new NullConfigurationPersister(), processState, ResourceBuilder.Factory.create(PathElement.pathElement("root"), new NonResolvingResourceDescriptionResolver()).build()); } protected void initModel(ManagementModel managementModel, Resource modelControllerResource) { ManagementResourceRegistration rootRegistration = managementModel.getRootResourceRegistration(); GlobalOperationHandlers.registerGlobalOperations(rootRegistration, processType); GlobalNotifications.registerGlobalNotifications(rootRegistration, processType); rootRegistration.registerOperationHandler(ValidateOperationHandler.DEFINITION, ValidateOperationHandler.INSTANCE); rootRegistration.registerOperationHandler(createOperationDefinition("Test"), new OperationStepHandler() { @Override public void execute(OperationContext context, ModelNode operation) { // no-op } }, true ); rootRegistration.registerOperationHandler(TestUtils.SETUP_OPERATION_DEF, new OperationStepHandler() { @Override public void execute(OperationContext context, ModelNode operation) throws OperationFailedException { ModelNode proxyModel = new ModelNode(); proxyModel.get("serverchild", "svrA", "name").set("serverA"); proxyModel.get("serverchild", "svrA", "child", "childA", "name").set("childName"); proxyModel.get("serverchild", "svrA", "child", "childA", "value").set("childValue"); AbstractControllerTestBase.createModel(context, proxyModel); } } ); ManagementResourceRegistration serverReg = rootRegistration.registerSubModel( new SimpleResourceDefinition(PathElement.pathElement("serverchild", "*"),new NonResolvingResourceDescriptionResolver())); serverReg.registerReadOnlyAttribute(createAttribute("name", ModelType.STRING), null); /*ManagementResourceRegistration serverReg = rootRegistration.registerSubModel(PathElement.pathElement("serverchild", "*"), new DescriptionProvider() { @Override public ModelNode getModelDescription(Locale locale) { ModelNode node = new ModelNode(); node.get(DESCRIPTION).set("A server child"); node.get(ATTRIBUTES, NAME, TYPE).set(ModelType.STRING); node.get(ATTRIBUTES, NAME, DESCRIPTION).set("The name of the server child"); node.get(ATTRIBUTES, NAME, REQUIRED).set(true); node.get(ATTRIBUTES, NAME, MIN_LENGTH).set(1); node.get(CHILDREN, "child", DESCRIPTION).set("The children of the server child"); node.get(CHILDREN, "child", MIN_OCCURS).set(1); node.get(CHILDREN, "child", MODEL_DESCRIPTION); return node; } });*/ ManagementResourceRegistration serverChildReg = serverReg.registerSubModel( new SimpleResourceDefinition(PathElement.pathElement("child", "*"),new NonResolvingResourceDescriptionResolver())); /*ManagementResourceRegistration serverChildReg = serverReg.registerSubModel(PathElement.pathElement("child", "*"), new DescriptionProvider() { @Override public ModelNode getModelDescription(Locale locale) { ModelNode node = new ModelNode(); node.get(DESCRIPTION).set("A named set of children"); node.get(ATTRIBUTES, NAME, TYPE).set(ModelType.STRING); node.get(ATTRIBUTES, NAME, DESCRIPTION).set("The name of the child"); node.get(ATTRIBUTES, NAME, REQUIRED).set(true); node.get(ATTRIBUTES, NAME, MIN_LENGTH).set(1); node.get(ATTRIBUTES, VALUE, TYPE).set(ModelType.STRING); node.get(ATTRIBUTES, VALUE, DESCRIPTION).set("The value of the child"); node.get(ATTRIBUTES, VALUE, REQUIRED).set(true); node.get(ATTRIBUTES, VALUE, MIN_LENGTH).set(1); return node; } });*/ serverChildReg.registerReadOnlyAttribute(createAttribute("name", ModelType.STRING), null); final AttributeDefinition value = createAttribute("value", ModelType.STRING); serverChildReg.registerReadWriteAttribute(value, null, new ModelOnlyWriteAttributeHandler(value)); serverChildReg.registerMetric(createMetric("metric", ModelType.STRING), GlobalOperationsTestCase.TestMetricHandler.INSTANCE); serverChildReg.registerOperationHandler(createOperationDefinition("test-op"), new OperationStepHandler() { @Override public void execute(OperationContext context, ModelNode operation) { } } ); } } }