/* * JBoss, Home of Professional Open Source. * Copyright 2015, 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.suites; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.COMPOSITE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CONTENT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DEPLOYMENT; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ENABLED; 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.HOST; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.IN_SERIES; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MAX_FAILED_SERVERS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_HEADERS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.RESPONSE; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ROLLOUT_PLAN; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_CONFIG; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_GROUP; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SERVER_GROUPS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.STEPS; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SYSTEM_PROPERTY; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.UNDEPLOY; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.URL; import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.nio.file.Files; 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.deployment.broken.ServiceActivatorDeployment; import org.jboss.as.test.integration.domain.management.util.DomainTestSupport; import org.jboss.as.test.integration.domain.management.util.DomainTestUtils; import org.jboss.as.test.integration.management.util.MgmtOperationException; import org.jboss.dmr.ModelNode; import org.jboss.msc.service.ServiceActivator; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; /** * Tests handling of a failed deployment rollout and the removal thereof. * * @author Brian Stansberry (c) 2015 Red Hat Inc. */ public class DeploymentRolloutFailureTestCase { private static final String BROKEN_DEPLOYMENT = "broken.jar"; private static final String MSG = "main-server-group"; private static final PathElement DEPLOYMENT_PATH = PathElement.pathElement(DEPLOYMENT, BROKEN_DEPLOYMENT); private static final PathElement MAIN_SERVER_GROUP = PathElement.pathElement(SERVER_GROUP, MSG); private static final PathAddress SYS_PROP_ADDR = PathAddress.pathAddress(PathElement.pathElement(HOST, "slave"), PathElement.pathElement(SERVER_CONFIG, "main-three"), PathElement.pathElement(SYSTEM_PROPERTY, ServiceActivatorDeployment.FAIL_SYS_PROP)); private static DomainTestSupport testSupport; private static DomainClient masterClient; private static File tmpDir; private static File deployment; @BeforeClass public static void setupDomain() throws Exception { testSupport = DomainTestSuite.createSupport(DeploymentRolloutFailureTestCase.class.getSimpleName()); masterClient = testSupport.getDomainMasterLifecycleUtil().getDomainClient(); File tmpRoot = new File(System.getProperty("java.io.tmpdir")); tmpDir = new File(tmpRoot, DeploymentRolloutFailureTestCase.class.getSimpleName() + System.currentTimeMillis()); Files.createDirectory(tmpDir.toPath()); deployment = new File(tmpDir, BROKEN_DEPLOYMENT); final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, BROKEN_DEPLOYMENT); archive.addClass(ServiceActivatorDeployment.class); archive.addAsServiceProvider(ServiceActivator.class, ServiceActivatorDeployment.class); archive.addAsManifestResource(new StringAsset("Dependencies: org.jboss.msc\n"), "MANIFEST.MF"); archive.as(ZipExporter.class).exportTo(deployment); } @AfterClass public static void tearDownDomain() throws Exception { testSupport = null; masterClient = null; DomainTestSuite.stopSupport(); if (deployment != null && !deployment.delete() && deployment.exists()) { deployment.deleteOnExit(); } if (tmpDir != null && !tmpDir.delete() && tmpDir.exists()) { tmpDir.deleteOnExit(); } } @After public void cleanup() throws IOException { try { cleanDeploymentFromServerGroup(); } catch (MgmtOperationException e) { // ignored } finally { try { cleanDeployment(); } catch (MgmtOperationException e) { // ignored } finally { try { cleanSystemProperty(); } catch (MgmtOperationException e1) { // ignored } } } } @Test public void test() throws IOException, MgmtOperationException { configureDeploymentFailure(); failInstallFailedDeployment(); succeedInstallFailedDeployment(); failRemoveFailedDeployment(); succeedRemoveFailedDeployment(); } private void configureDeploymentFailure() throws IOException, MgmtOperationException { ModelNode op = Util.createAddOperation(SYS_PROP_ADDR); op.get(VALUE).set("true"); DomainTestUtils.executeForResult(op, masterClient); } private void failInstallFailedDeployment() throws IOException, MgmtOperationException { ModelNode op = getDeploymentCompositeOp(); final ModelNode ret = masterClient.execute(op); if (! FAILED.equals(ret.get(OUTCOME).asString())) { throw new MgmtOperationException("Management operation succeeded.", op, ret); } // Validate the server results are included ModelNode m3Resp = ret.get(SERVER_GROUPS, MSG, HOST, "slave", "main-three", RESPONSE); Assert.assertTrue(ret.toString(), m3Resp.isDefined()); Assert.assertEquals(m3Resp.toString(), FAILED, m3Resp.get(OUTCOME).asString()); Assert.assertTrue(m3Resp.toString(), m3Resp.get(FAILURE_DESCRIPTION).asString().contains(ServiceActivatorDeployment.FAILURE_MESSAGE)); ModelNode failDesc = ret.get(FAILURE_DESCRIPTION); Assert.assertTrue(failDesc.toString(), failDesc.isDefined()); ModelNode servers = failDesc.asProperty().getValue(); Assert.assertTrue(failDesc.toString(), servers.isDefined()); ModelNode serverFail = servers.get(SERVER_GROUP, MSG, HOST, "slave", "main-three"); Assert.assertTrue(failDesc.toString(), serverFail.isDefined()); Assert.assertTrue(failDesc.toString(), serverFail.toString().contains(ServiceActivatorDeployment.FAILURE_MESSAGE)); } private ModelNode getDeploymentCompositeOp() throws MalformedURLException { ModelNode op = new ModelNode(); op.get(OP).set(COMPOSITE); ModelNode steps = op.get(STEPS); ModelNode depAdd = Util.createAddOperation(PathAddress.pathAddress(DEPLOYMENT_PATH)); ModelNode content = new ModelNode(); content.get(URL).set(deployment.toURI().toURL().toString()); depAdd.get(CONTENT).add(content); steps.add(depAdd); ModelNode sgAdd = Util.createAddOperation(PathAddress.pathAddress(MAIN_SERVER_GROUP, DEPLOYMENT_PATH)); sgAdd.get(ENABLED).set(true); steps.add(sgAdd); return op; } private void succeedInstallFailedDeployment() throws IOException, MgmtOperationException { ModelNode op = getDeploymentCompositeOp(); op.get(OPERATION_HEADERS, ROLLOUT_PLAN).set(getRolloutPlanO()); DomainTestUtils.executeForResult(op, masterClient); } private ModelNode getRolloutPlanO() { ModelNode plan = new ModelNode(); ModelNode sg = plan.get(IN_SERIES).add().get(SERVER_GROUP, "main-server-group"); sg.get(MAX_FAILED_SERVERS).set(1); return plan; } private void failRemoveFailedDeployment() throws IOException, MgmtOperationException { ModelNode op = getUndeployCompositeOp(); final ModelNode ret = masterClient.execute(op); if (! FAILED.equals(ret.get(OUTCOME).asString())) { throw new MgmtOperationException("Management operation succeeded.", op, ret); } // Validate the server results are included ModelNode m3Resp = ret.get(SERVER_GROUPS, MSG, HOST, "slave", "main-three", RESPONSE); Assert.assertTrue(ret.toString(), m3Resp.isDefined()); Assert.assertEquals(m3Resp.toString(), FAILED, m3Resp.get(OUTCOME).asString()); Assert.assertTrue(m3Resp.toString(), m3Resp.get(FAILURE_DESCRIPTION).isDefined()); ModelNode failDesc = ret.get(FAILURE_DESCRIPTION); Assert.assertTrue(failDesc.toString(), failDesc.isDefined()); ModelNode servers = failDesc.asProperty().getValue(); Assert.assertTrue(failDesc.toString(), servers.isDefined()); ModelNode serverFail = servers.get(SERVER_GROUP, MSG, HOST, "slave", "main-three"); Assert.assertTrue(failDesc.toString(), serverFail.isDefined()); } private ModelNode getUndeployCompositeOp() throws MalformedURLException { ModelNode op = new ModelNode(); op.get(OP).set(COMPOSITE); ModelNode steps = op.get(STEPS); PathAddress sgDep = PathAddress.pathAddress(MAIN_SERVER_GROUP, DEPLOYMENT_PATH); steps.add(Util.createEmptyOperation(UNDEPLOY, sgDep)); steps.add(Util.createRemoveOperation(sgDep)); steps.add(Util.createRemoveOperation(PathAddress.pathAddress(DEPLOYMENT_PATH))); return op; } private void succeedRemoveFailedDeployment() throws IOException, MgmtOperationException { ModelNode op = getUndeployCompositeOp(); op.get(OPERATION_HEADERS, ROLLOUT_PLAN).set(getRolloutPlanO()); DomainTestUtils.executeForResult(op, masterClient); } private void cleanDeploymentFromServerGroup() throws IOException, MgmtOperationException { ModelNode op = Util.createRemoveOperation(PathAddress.pathAddress(MAIN_SERVER_GROUP, DEPLOYMENT_PATH)); op.get(ENABLED).set(true); op.get(OPERATION_HEADERS, ROLLOUT_PLAN).set(getRolloutPlanO()); DomainTestUtils.executeForResult(op, masterClient); } private void cleanDeployment() throws IOException, MgmtOperationException { ModelNode op = Util.createRemoveOperation(PathAddress.pathAddress(DEPLOYMENT_PATH)); DomainTestUtils.executeForResult(op, masterClient); } private void cleanSystemProperty() throws IOException, MgmtOperationException { ModelNode op = Util.createRemoveOperation(SYS_PROP_ADDR); DomainTestUtils.executeForResult(op, masterClient); } }