/* * JBoss, Home of Professional Open Source * Copyright 2010-2016, Red Hat, Inc. and individual contributors * 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.richfaces.tests.metamer.ftest.extension.arquillian; import static java.text.MessageFormat.format; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.jboss.arquillian.container.spi.event.container.BeforeStart; import org.jboss.arquillian.core.api.annotation.Observes; import org.jboss.as.cli.CommandLineException; import com.google.common.io.Files; /** * Installs patch from System property <code>pathToPatch</code> to JBoss container using the jboss-cli.sh script. * * @author <a href="mailto:jstefek@redhat.com">Jiri Stefek</a> */ public class JBossPatchInstaller { private static final String ACTIVATED_MAVEN_PROFILES = System.getProperty("activated.maven.profiles", ""); private static final String JBOSS_HOME_SYSTEM_PROPERTY = "JBOSS_HOME"; private static final String OS_NAME = System.getProperty("os.name"); private static final String PATH_TO_JBOSS_HOME = System.getProperty(JBOSS_HOME_SYSTEM_PROPERTY); private static final String PATH_TO_JBOSS_PATCH_SYSTEM_PROPERTY = "pathToPatch"; private static final String SUCCESS_STRING = "success"; private static String formatOutput(List<String> outputFromProcess) { StringBuilder sb = new StringBuilder(100); boolean performed = false; for (String o : outputFromProcess) { if (performed) { sb.append("\n"); } sb.append(" * ").append(o); performed = true; } return sb.toString(); } private static boolean isUsingJBossContainer() { return ACTIVATED_MAVEN_PROFILES.contains("jbosseap") || ACTIVATED_MAVEN_PROFILES.contains("wildfly"); } /** * Apply patch from given path. */ private void applyPatch(String pathToPatch) throws CommandLineException { if (PATH_TO_JBOSS_HOME == null || PATH_TO_JBOSS_HOME.isEmpty()) { logError("JBOSS_HOME not detected. Exiting."); System.exit(1); } logInfoMarked(format("Applying patch from path <{0}>", pathToPatch)); try { File f = new File(PATH_TO_JBOSS_HOME + "/bin/jboss-cli" + (isOnWindows() ? ".bat" : ".sh")); f.setExecutable(true); File patch = new File(pathToPatch); String patchName = patch.getName(); File patchCopy = new File("target/" + patchName); logInfo(format("Copying patch <{0}> to <{1}> for easier manipulation.", patch.getAbsolutePath(), patchCopy.getAbsolutePath())); Files.copy(patch, patchCopy); String cmd = f.getAbsolutePath() + " --command=\"patch apply " + patchCopy.getAbsolutePath() + "\""; String[] cmdArray; if (isOnWindows()) { // the cmd.exe is hanging with 'Press any key to continue ...' // give it some input from empty temporary file to workaround this File tmp = new File("tempFile"); tmp.createNewFile(); tmp.deleteOnExit(); cmdArray = new String[] { "cmd.exe", "/C", cmd + " < " + tmp.getAbsolutePath() }; } else { cmdArray = new String[] { "/bin/sh", "-c", cmd }; } logInfo("Applying patch " + patchCopy.getName()); // apply patch by running jboss-cli.sh with parameters Process p = Runtime.getRuntime().exec(cmdArray); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); // check stdin contains success String s; boolean success = false; List<String> outputFromProcess = new ArrayList<String>(10); while ((s = stdInput.readLine()) != null) { outputFromProcess.add(s); if (s.toLowerCase().contains(SUCCESS_STRING)) { success = true;// do not break here, consume all the input } } stdInput.close(); p.destroy(); // check stdin contained success, otherwise immediatelly exit if (!success) { logError(format("Attempt to apply a patch was not succesfull. Apllying patch ended with output:\n{0}", formatOutput(outputFromProcess))); logError("Exiting."); System.exit(1); } } catch (IOException ex) { logError(ex.toString()); logError("Attempt to apply a patch was not succesfull. Exiting."); System.exit(1); } logInfoMarked("Patch applied succesfully"); } public void applyPatchWhenNeeded(@Observes BeforeStart event) { String pathToPatch = System.getProperty(PATH_TO_JBOSS_PATCH_SYSTEM_PROPERTY); if (!isUsingJBossContainer() || pathToPatch == null || pathToPatch.isEmpty()) { logInfoMarked("No patch to apply."); } else { if (new File(pathToPatch).exists()) { try { applyPatch(pathToPatch); } catch (CommandLineException e) { logError(e.toString()); logError("Was not able to apply the patch. Exiting."); System.exit(1); } } else { logError(format("The patch at <{0}> does not exist. Exiting.", pathToPatch)); System.exit(1); } } } private boolean isOnWindows() { return OS_NAME.toLowerCase().contains("win"); } private void logError(String msg) { System.err.println(msg); } private void logInfo(String msg) { System.out.println(format(" * {0}", msg)); } private void logInfoMarked(String msg) { System.out.println(format("### {0} ###", msg)); } }