/* * JBoss, Home of Professional Open Source * Copyright 2015, Red Hat Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt 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.suites; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADMIN_ONLY; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CHILD_TYPE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CLONE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CORE_SERVICE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DOMAIN_CONTROLLER; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HOST; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.IGNORED_RESOURCES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.IGNORED_RESOURCE_TYPE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.IGNORE_UNUSED_CONFIG; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAMES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PROFILE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_CHILDREN_NAMES_OPERATION; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOTE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESTART_SERVERS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TO_PROFILE; import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.List; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.client.helpers.domain.DomainClient; import org.jboss.as.controller.operations.common.Util; import org.jboss.as.test.integration.domain.management.util.DomainLifecycleUtil; 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.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import org.xnio.IoUtils; /** * Tests effect of ignoring profiles when profiles are cloned * * @author Kabir Khan */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class IgnoredResourcesProfileCloneTestCase { private static final String ORIGINAL_PROFILE = "default"; ///The testsuite host-slave.xml is set up to ignore this profile private static final String IGNORED_PROFILE = "ignored"; //This test sets up another profile which should be ignored private static final String IGNORE_TO_PROFILE = "ignore-to"; private static final String CLONED_PROFILE = "cloned-profile"; private static final PathAddress SLAVE_ADDR = PathAddress.pathAddress(HOST, "slave"); private static DomainTestSupport testSupport; private static DomainLifecycleUtil masterLifecycleUtil; private static DomainLifecycleUtil slaveLifecycleUtil; @BeforeClass public static void beforeClass() throws Exception { testSupport = DomainTestSuite.createSupport(IgnoredResourcesProfileCloneTestCase.class.getSimpleName()); masterLifecycleUtil = testSupport.getDomainMasterLifecycleUtil(); slaveLifecycleUtil = testSupport.getDomainSlaveLifecycleUtil(); } @AfterClass public static void afterClass() throws Exception { slaveLifecycleUtil.awaitServers(System.currentTimeMillis()); testSupport = null; masterLifecycleUtil = null; slaveLifecycleUtil = null; DomainTestSuite.stopSupport(); } @Test public void test01_ProfileCloneIgnoredWithIgnoreUnusedConfiguration() throws Exception { final DomainClient masterClient = masterLifecycleUtil.getDomainClient(); final DomainClient slaveClient = slaveLifecycleUtil.getDomainClient(); try { final ModelNode originalSlaveDc = DomainTestUtils.executeForResult( Util.getReadAttributeOperation(SLAVE_ADDR, DOMAIN_CONTROLLER), masterClient).get(REMOTE); originalSlaveDc.protect(); if (originalSlaveDc.hasDefined(IGNORE_UNUSED_CONFIG) && !originalSlaveDc.get(IGNORE_UNUSED_CONFIG).asBoolean()) { Assert.fail("ignore-unused-config should be undefined or true"); } // clone profile ModelNode clone = Util.createEmptyOperation(CLONE, PathAddress.pathAddress(PROFILE, ORIGINAL_PROFILE)); clone.get(TO_PROFILE).set(CLONED_PROFILE); DomainTestUtils.executeForResult(clone, masterClient); try { // get and check submodules List<String> originalSubsystems = getSubsystems(ORIGINAL_PROFILE, masterClient); List<String> newSubsystems = getSubsystems(CLONED_PROFILE, masterClient); assertEquals(originalSubsystems, newSubsystems); //Since the slave ignores unused config, the new profile should not exist on the slave List<String> slaveSubsystems = getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, slaveClient); Assert.assertTrue(slaveSubsystems.contains(ORIGINAL_PROFILE)); Assert.assertFalse(slaveSubsystems.contains(CLONED_PROFILE)); } finally { DomainTestUtils.executeForResult(Util.createRemoveOperation(PathAddress.pathAddress(PROFILE, CLONED_PROFILE)), masterClient); } } finally { IoUtils.safeClose(slaveClient); IoUtils.safeClose(masterClient); } } @Test public void test02_ProfileCloneIgnoredWithoutIgnoreUnusedConfiguration() throws Exception { final DomainClient masterClient = masterLifecycleUtil.getDomainClient(); DomainClient slaveClient = slaveLifecycleUtil.getDomainClient(); try { final ModelNode originalSlaveDc = DomainTestUtils.executeForResult( Util.getReadAttributeOperation(SLAVE_ADDR, DOMAIN_CONTROLLER), masterClient).get(REMOTE); originalSlaveDc.protect(); final PathAddress profileIgnoreAddress = PathAddress.pathAddress(SLAVE_ADDR.append(CORE_SERVICE, IGNORED_RESOURCES).append(IGNORED_RESOURCE_TYPE, PROFILE)); final ModelNode originalIgnores = DomainTestUtils.executeForResult(Util.getReadAttributeOperation(profileIgnoreAddress, NAMES), slaveClient); originalIgnores.protect(); try { //Turn off the slave's ignore-unused-config setting, add an ignore for 'ignore-to' and reload it ModelNode newSlaveDc = originalSlaveDc.clone(); newSlaveDc.get(IGNORE_UNUSED_CONFIG).set(false); writeSlaveDomainController(slaveClient, newSlaveDc); DomainTestUtils.executeForResult( Util.getWriteAttributeOperation(profileIgnoreAddress, NAMES, originalIgnores.clone().add(IGNORE_TO_PROFILE)), slaveClient); reloadSlave(slaveLifecycleUtil); slaveClient = slaveLifecycleUtil.getDomainClient(); //////////////////////////////////////////////////////////////////////////////////////////////////////// //Clone profile which is not ignored //It should appear on the slave, and the host state should be running ModelNode clone = Util.createEmptyOperation(CLONE, PathAddress.pathAddress(PROFILE, ORIGINAL_PROFILE)); clone.get(TO_PROFILE).set(CLONED_PROFILE); DomainTestUtils.executeForResult(clone, masterClient); try { List<String> masterProfiles = getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, masterClient); Assert.assertTrue(masterProfiles.remove(IGNORED_PROFILE)); Assert.assertEquals(masterProfiles, getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, slaveClient)); Assert.assertEquals(getSubsystems(ORIGINAL_PROFILE, masterClient), getSubsystems(ORIGINAL_PROFILE, slaveClient)); Assert.assertEquals(getSubsystems(CLONED_PROFILE, masterClient), getSubsystems(CLONED_PROFILE, slaveClient)); DomainTestUtils.executeForResult( Util.getWriteAttributeOperation( PathAddress.pathAddress(PROFILE, CLONED_PROFILE).append(SUBSYSTEM, "jmx"), "non-core-mbean-sensitivity", new ModelNode(true)), masterClient); } finally { DomainTestUtils.executeForResult(Util.createRemoveOperation(PathAddress.pathAddress(PROFILE, CLONED_PROFILE)), masterClient); } Assert.assertEquals("running", getSlaveState(slaveClient)); //////////////////////////////////////////////////////////////////////////////////////////////////////// //Clone profile which is ignored //It should not appear on the slave and the slave should be reload-required clone = Util.createEmptyOperation(CLONE, PathAddress.pathAddress(PROFILE, IGNORED_PROFILE)); clone.get(TO_PROFILE).set(CLONED_PROFILE); DomainTestUtils.executeForResult(clone, masterClient); try { Assert.assertEquals("reload-required", getSlaveState(slaveClient)); List<String> masterProfiles = getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, masterClient); Assert.assertTrue(masterProfiles.remove(IGNORED_PROFILE)); Assert.assertTrue(masterProfiles.remove(CLONED_PROFILE)); Assert.assertEquals(masterProfiles, getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, slaveClient)); DomainTestUtils.executeForResult( Util.getWriteAttributeOperation( PathAddress.pathAddress(PROFILE, CLONED_PROFILE).append(SUBSYSTEM, "jmx"), "non-core-mbean-sensitivity", new ModelNode(true)), masterClient); } finally { DomainTestUtils.executeForResult(Util.createRemoveOperation(PathAddress.pathAddress(PROFILE, CLONED_PROFILE)), masterClient); } reloadSlave(slaveLifecycleUtil); //Clone profile which is ignored again, it should not appear on the slave and the slave should be reload-required DomainTestUtils.executeForResult(clone, masterClient); try { Assert.assertEquals("reload-required", getSlaveState(slaveClient)); List<String> masterProfiles = getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, masterClient); Assert.assertTrue(masterProfiles.remove(IGNORED_PROFILE)); Assert.assertTrue(masterProfiles.remove(CLONED_PROFILE)); Assert.assertEquals(masterProfiles, getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, slaveClient)); //The reload should bring down the new profile reloadSlave(slaveLifecycleUtil); masterProfiles = getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, masterClient); Assert.assertTrue(masterProfiles.remove(IGNORED_PROFILE)); Assert.assertEquals(masterProfiles, getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, slaveClient)); DomainTestUtils.executeForResult( Util.getWriteAttributeOperation( PathAddress.pathAddress(PROFILE, CLONED_PROFILE).append(SUBSYSTEM, "jmx"), "non-core-mbean-sensitivity", new ModelNode(true)), masterClient); } finally { DomainTestUtils.executeForResult(Util.createRemoveOperation(PathAddress.pathAddress(PROFILE, CLONED_PROFILE)), masterClient); } Assert.assertEquals("running", getSlaveState(slaveClient)); //////////////////////////////////////////////////////////////////////////////////////////////////////// //Clone profile where the to-profile is ignored //It should not appear on the slave, and the slave should be in the running state clone = Util.createEmptyOperation(CLONE, PathAddress.pathAddress(PROFILE, ORIGINAL_PROFILE)); clone.get(TO_PROFILE).set(IGNORE_TO_PROFILE); DomainTestUtils.executeForResult(clone, masterClient); try { List<String> masterProfiles = getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, masterClient); Assert.assertTrue(masterProfiles.remove(IGNORED_PROFILE)); Assert.assertTrue(masterProfiles.remove(IGNORE_TO_PROFILE)); Assert.assertEquals(masterProfiles, getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, slaveClient)); DomainTestUtils.executeForResult( Util.getWriteAttributeOperation( PathAddress.pathAddress(PROFILE, IGNORE_TO_PROFILE).append(SUBSYSTEM, "jmx"), "non-core-mbean-sensitivity", new ModelNode(true)), masterClient); } finally { DomainTestUtils.executeForResult(Util.createRemoveOperation(PathAddress.pathAddress(PROFILE, IGNORE_TO_PROFILE)), masterClient); } Assert.assertEquals("running", getSlaveState(slaveClient)); //////////////////////////////////////////////////////////////////////////////////////////////////////// //Clone profile where both the original and the to profiles are cloned. //It should not appear on the slave, and the slave should be in the running state clone = Util.createEmptyOperation(CLONE, PathAddress.pathAddress(PROFILE, IGNORED_PROFILE)); clone.get(TO_PROFILE).set(IGNORE_TO_PROFILE); DomainTestUtils.executeForResult(clone, masterClient); try { List<String> masterProfiles = getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, masterClient); Assert.assertTrue(masterProfiles.remove(IGNORED_PROFILE)); Assert.assertTrue(masterProfiles.remove(IGNORE_TO_PROFILE)); Assert.assertEquals(masterProfiles, getChildNames(PathAddress.EMPTY_ADDRESS, PROFILE, slaveClient)); DomainTestUtils.executeForResult( Util.getWriteAttributeOperation( PathAddress.pathAddress(PROFILE, IGNORE_TO_PROFILE).append(SUBSYSTEM, "jmx"), "non-core-mbean-sensitivity", new ModelNode(true)), masterClient); } finally { DomainTestUtils.executeForResult(Util.createRemoveOperation(PathAddress.pathAddress(PROFILE, IGNORE_TO_PROFILE)), masterClient); } Assert.assertEquals("running", getSlaveState(slaveClient)); } finally { writeSlaveDomainController(slaveClient, originalSlaveDc); DomainTestUtils.executeForResult(Util.getWriteAttributeOperation(profileIgnoreAddress, NAMES, originalIgnores), slaveClient); reloadSlave(slaveLifecycleUtil); } } finally { IoUtils.safeClose(slaveClient); IoUtils.safeClose(masterClient); } } private static void reloadSlave(DomainLifecycleUtil slaveLifecycleUtil) throws Exception { ModelNode reload = Util.createEmptyOperation("reload", PathAddress.pathAddress(HOST, "slave")); reload.get(RESTART_SERVERS).set(false); reload.get(ADMIN_ONLY).set(false); slaveLifecycleUtil.executeAwaitConnectionClosed(reload); slaveLifecycleUtil.connect(); slaveLifecycleUtil.awaitHostController(System.currentTimeMillis()); } private List<String> getSubsystems(String profile, DomainClient client) throws Exception { return getChildNames(PathAddress.pathAddress(PROFILE, profile), SUBSYSTEM, client); } private List<String> getChildNames(PathAddress parent, String childType, DomainClient client) throws Exception { ModelNode readChildrenNames = Util.createEmptyOperation(READ_CHILDREN_NAMES_OPERATION, parent); readChildrenNames.get(CHILD_TYPE).set(childType); ModelNode result = DomainTestUtils.executeForResult(readChildrenNames, client); List<String> list = new ArrayList<>(); for (ModelNode element : result.asList()) { list.add(element.asString()); } return list; } private void writeSlaveDomainController(DomainClient slaveClient, ModelNode remoteDc) throws Exception{ DomainTestUtils.executeForResult(Util.createEmptyOperation("remove-remote-domain-controller", SLAVE_ADDR), slaveClient); ModelNode writeRemoteDc = Util.createEmptyOperation("write-remote-domain-controller", SLAVE_ADDR); for (String key : remoteDc.keys()) { writeRemoteDc.get(key).set(remoteDc.get(key)); } DomainTestUtils.executeForResult(writeRemoteDc, slaveClient); } private String getSlaveState(DomainClient slaveClient) throws Exception { return DomainTestUtils.executeForResult(Util.getReadAttributeOperation(SLAVE_ADDR, "host-state"), slaveClient).asString(); } }