/* * JBoss, Home of Professional Open Source. * Copyright ${year}, 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.test.integration.domain.slavereconnect; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD_INDEX; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.EXTENSION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HOST; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PROFILE; 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.RELOAD_REQUIRED; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_CONFIG; import java.util.Set; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathElement; import org.jboss.as.controller.client.helpers.domain.DomainClient; import org.jboss.as.controller.operations.common.Util; import org.jboss.as.test.integration.domain.extension.ExtensionSetup; import org.jboss.as.test.integration.domain.extension.OrderedChildResourceExtension; import org.jboss.as.test.integration.domain.management.util.DomainTestSupport; import org.jboss.as.test.integration.domain.management.util.DomainTestUtils; import org.jboss.dmr.ModelNode; import org.junit.Assert; /** * Tests ordered child resources on reconnect * * @author <a href="mailto:kabir.khan@jboss.com">Kabir Khan</a> */ public class OrderedChildResourceScenario extends ReconnectTestScenario { private static final PathAddress EXTENSION_ADDRESS = PathAddress.pathAddress(EXTENSION, OrderedChildResourceExtension.MODULE_NAME); private static final PathAddress SUBSYSTEM_ADDRESS = PathAddress.pathAddress(PROFILE, "default").append(OrderedChildResourceExtension.SUBSYSTEM_PATH); private static final PathAddress MASTER_SERVER_SUBSYSTEM_ADDRESS = PathAddress.pathAddress(HOST, "master").append(SERVER, "main-one").append(OrderedChildResourceExtension.SUBSYSTEM_PATH); private static final PathAddress SLAVE_SERVER_ADDRESS = PathAddress.pathAddress(HOST, "slave").append(SERVER, "main-three"); private static final PathAddress SLAVE_SERVER_SUBSYSTEM_ADDRESS = SLAVE_SERVER_ADDRESS.append(OrderedChildResourceExtension.SUBSYSTEM_PATH); //Just to know how much was initialised in the setup method, so we know what to tear down private int initialised = 0; @Override void setUpDomain(DomainTestSupport testSupport, DomainClient masterClient, DomainClient slaveClient) throws Exception { // Initialize the test extension ExtensionSetup.initializeOrderedChildResourceExtension(testSupport); DomainTestUtils.executeForResult(Util.createAddOperation(PathAddress.pathAddress(EXTENSION_ADDRESS)), masterClient); initialised = 1; //Add the subsystem DomainTestUtils.executeForResult(Util.createAddOperation(SUBSYSTEM_ADDRESS), masterClient); initialised = 2; } @Override void tearDownDomain(DomainClient masterClient, DomainClient slaveClient) throws Exception { if (initialised >=2) { DomainTestUtils.executeForResult(Util.createRemoveOperation(SUBSYSTEM_ADDRESS), masterClient); } if (initialised >= 1) { DomainTestUtils.executeForResult(Util.createRemoveOperation(PathAddress.pathAddress(EXTENSION_ADDRESS)), masterClient); } } @Override void testOnInitialStartup(DomainClient masterClient, DomainClient slaveClient) throws Exception { checkDomainChildOrder(masterClient); compareSubsystemModels(masterClient, slaveClient); //Now add some child resources addChild(masterClient, "Z", -1); checkDomainChildOrder(masterClient, "Z"); compareSubsystemModels(masterClient, slaveClient); //Try an indexed add addChild(masterClient, "N", 0); checkDomainChildOrder(masterClient, "N", "Z"); compareSubsystemModels(masterClient, slaveClient); } @Override void testWhileMasterInAdminOnly(DomainClient masterClient, DomainClient slaveClient) throws Exception { //Execute an indexed add op on the DC. The DC should change, //but the slave should stay the same since the DC is now in admin-only mode addChild(masterClient, "S", 1); //Check the domain model rather than the slave model since the DC is admin-only checkDomainChildOrder(masterClient, SUBSYSTEM_ADDRESS, "N", "S", "Z"); checkDomainChildOrder(slaveClient, SUBSYSTEM_ADDRESS, "N", "Z"); } @Override void testAfterReconnect(DomainClient masterClient, DomainClient slaveClient) throws Exception { //Check the slave again after reboot checkDomainChildOrder(masterClient, "N", "S", "Z"); // Might need to loop a bit here to make sure that the fresh domain model gets pulled down compareSubsystemModels(masterClient, slaveClient, true); ModelNode reloadServer = Util.createEmptyOperation("reload", PathAddress.pathAddress(HOST, "slave").append(SERVER_CONFIG, "main-three")); reloadServer.get("blocking").set(true); DomainTestUtils.executeForResult(reloadServer, slaveClient); compareSubsystemModels(masterClient, slaveClient); } private void addChild(DomainClient masterClient, String childName, int index) throws Exception { final ModelNode op = Util.createAddOperation(SUBSYSTEM_ADDRESS.append(PathElement.pathElement(OrderedChildResourceExtension.CHILD.getKey(), childName))); op.get("attr").set(childName.toLowerCase()); if (index >= 0) { op.get(ADD_INDEX).set(index); } DomainTestUtils.executeForResult(op, masterClient); } private void checkDomainChildOrder(DomainClient client, String...childNames ) throws Exception { checkDomainChildOrder(client, MASTER_SERVER_SUBSYSTEM_ADDRESS, childNames); } private void checkDomainChildOrder(DomainClient client, PathAddress address, String...childNames ) throws Exception { final ModelNode result = DomainTestUtils.executeForResult(getRecursiveReadResourceOperation(address), client); if (childNames.length > 0) { Assert.assertTrue(result.hasDefined(OrderedChildResourceExtension.CHILD.getKey())); Set<String> childKeys = result.get(OrderedChildResourceExtension.CHILD.getKey()).keys(); String[] childKeyArray = childKeys.toArray(new String[childKeys.size()]); Assert.assertArrayEquals(childNames, childKeyArray); } else { Assert.assertFalse(result.hasDefined(OrderedChildResourceExtension.CHILD.getKey())); } } private ModelNode compareSubsystemModels(DomainClient masterClient, DomainClient slaveClient) throws Exception { return compareSubsystemModels(masterClient, slaveClient, false); } private ModelNode compareSubsystemModels(DomainClient masterClient, DomainClient slaveClient, boolean serverReload) throws Exception { final ModelNode domain = DomainTestUtils.executeForResult(getRecursiveReadResourceOperation(SUBSYSTEM_ADDRESS), masterClient); Assert.assertEquals(domain, DomainTestUtils.executeForResult(getRecursiveReadResourceOperation(SUBSYSTEM_ADDRESS), slaveClient)); Assert.assertEquals(domain, DomainTestUtils.executeForResult(getRecursiveReadResourceOperation(MASTER_SERVER_SUBSYSTEM_ADDRESS), masterClient)); if (!serverReload) { //A reconnect with a changed model does not propagate the model changes to the servers, but puts them in reload-required Assert.assertEquals(domain, DomainTestUtils.executeForResult(getRecursiveReadResourceOperation(SLAVE_SERVER_SUBSYSTEM_ADDRESS), masterClient)); } String runtimeConfigurationState = DomainTestUtils.executeForResult(Util.getReadAttributeOperation(SLAVE_SERVER_ADDRESS, "runtime-configuration-state"), masterClient).asString(); Assert.assertEquals(serverReload ? RELOAD_REQUIRED : "ok", runtimeConfigurationState); String serverState = DomainTestUtils.executeForResult(Util.getReadAttributeOperation(SLAVE_SERVER_ADDRESS, "server-state"), masterClient).asString(); Assert.assertEquals(serverReload ? RELOAD_REQUIRED : "running", serverState); return domain; } private ModelNode getRecursiveReadResourceOperation(PathAddress address) { final ModelNode op = Util.createOperation(READ_RESOURCE_OPERATION, address); op.get(RECURSIVE).set(true); return op; } }