/* * JBoss, Home of Professional Open Source * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * 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, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2008, * @author JBoss Inc. */ package org.jboss.test.jbossts.taskdefs; import org.apache.tools.ant.Task; import org.apache.tools.ant.BuildException; import org.jboss.test.jbossts.recovery.ASFailureSpec; import org.jboss.jbossas.servermanager.Server; import org.jboss.jbossas.servermanager.ServerManager; import org.xml.sax.SAXException; import javax.naming.NamingException; import javax.naming.Context; import javax.xml.transform.TransformerException; import javax.xml.parsers.ParserConfigurationException; import java.util.*; import java.io.File; import java.io.IOException; /** * Ant task for capturing common configuration for a group of tests * defined in an ant build script. */ public class ASTestConfig extends Task { // arbitary handle for refering to the unique instance of the task configuration public static final String CONFIG_REF = "asTestConfig"; // the name of the system property holding the path the product directory public final static String PRODUCT_DIR_PROP = "product.dir"; // the location of a JBoss distribution relative to the product directory private final static String AS_ROOT_DIR = "/as/"; private List<ASFailureSpec> specs = new ArrayList<ASFailureSpec>(); private Map<String, ASFailureSpec> specMap = new HashMap<String, ASFailureSpec>(); private String productDir; private boolean isDebug = false; private ServerManager manager = new ServerManager(); public void execute() throws BuildException { System.setSecurityManager(new java.rmi.RMISecurityManager()); // The Task Runner should have set the product directory productDir = System.getProperty(PRODUCT_DIR_PROP); if (productDir == null) throw new BuildException("Please specify the location of the product directory via the \""+ PRODUCT_DIR_PROP + "\" system property"); productDir = Utils.toFile(productDir).getAbsolutePath(); if (!productDir.endsWith("/")) productDir += '/'; if (isDebug) System.out.println("ASCrashConfig: productDir=" + productDir + " and jbossHome=" + manager.getJBossHome()); if (manager.getJBossHome() == null) { File jbh = Utils.toFile(productDir + AS_ROOT_DIR); if (isDebug) System.out.println("ASCrashConfig: jbh=" + jbh.getAbsolutePath() + " exists=" + jbh.exists()); if (jbh.exists()) setJbossHome(jbh.getAbsolutePath()); else setJbossHome(System.getenv("JBOSS_HOME")); } // add this to the ant project so that other tasks are able to locate this if (getProject().getReference(CONFIG_REF) == null) getProject().addReference(CONFIG_REF, this); ASFailureSpec[] sa = getSpecs(); // read in any failure specifications so that an ant target may look them up for (ASFailureSpec fs : sa) specMap.put(fs.getName(), fs); if (isDebug) { StringBuilder sb = new StringBuilder(); sb.append("configuring ").append(specs.size()).append(" crash specifications:\n"); for (ASFailureSpec spec : specs) { sb.append("\t").append(spec).append('\n'); } System.out.print(sb); } } /** * Task parameter to add a fault injection specification. * * @param spec definition of the fault */ public void addSpec(ASFailureSpec spec) { specs.add(spec); } public ASFailureSpec getSpec(String spec) { return specMap.get(spec); } public ASFailureSpec[] getSpecs() { ASFailureSpec[] sa = new ASFailureSpec[specs.size()]; return specs.toArray(sa); } public ASFailureSpec[] parseSpecs(String specArg) { String[] specs = specArg.split(","); ASFailureSpec[] fspecs = new ASFailureSpec[specs.length]; for (int i = 0; i < specs.length; i++) fspecs[i] = getSpec(specs[i].trim()); return fspecs; } /** * Task parameter to add a server. * * @param server the server */ public void addServer(Server server) { manager.addServer(server); } /** * JAVA_HOME to start jboss with. * * @param javaHome Path to the the java installation */ public void setJavaHome(String javaHome) { manager.setJavaHome(javaHome); } public String getJBossHome() { return manager.getJBossHome(); } /** * JBoss dist to start. The default is to use the AS installed with the product. * If no AS can be found then the environment variable JBOSS_HOME is used * * @param jbossHome Path to the the jboss installation */ public void setJbossHome(String jbossHome) { manager.setJbossHome(jbossHome); } /** * JVM command to use default is "java" * @param jvm JVM command */ public void setJvm(String jvm) { manager.setJvm(jvm); } /** * The UDP group to pass to org.jboss.Main using * the -u option. * * @param udpGroup the udp group */ public void setUdpGroup(String udpGroup) { manager.setUdpGroup(udpGroup); } public void setDebug(boolean debug) { isDebug = debug; } /** * * @return the location where the product being tested is installed */ public String getProductDir() { return productDir; } /** * Return the nameing context that a given server is providing * * @param serverName the server providing the context * @return a naming context */ public Context getNamingContext(String serverName) { try { Server server = manager.getServer(serverName); return (server != null ? server.getNamingContext() : null); } catch (NamingException e) { e.printStackTrace(); throw new BuildException(e); } } /** * * @param serverName the name of the server whose path is being sought * @return the path to the JBoss instance corresponding to the provided name */ public String getServerPath(String serverName) { return getJBossHome() + "/server/" + serverName + '/'; } /** * Start a JBoss instance in a new VM * * @param serverName name of the target instance * @throws IOException If another process is already using a port required by this instance * @see org.jboss.jbossas.servermanager.ServerController#startServer(org.jboss.jbossas.servermanager.Server, org.jboss.jbossas.servermanager.ServerManager) */ public void startServer(String serverName) throws IOException { Server server = manager.getServer(serverName); // Warning !server.isRunning() is not equivalent to server.isStopped() // !server.isRunning() and !server.isStopped() implies that some other entity terminated the server if (!server.isRunning()) manager.startServer(serverName); } /** * @see org.jboss.jbossas.servermanager.ServerController#stopServer(org.jboss.jbossas.servermanager.Server, org.jboss.jbossas.servermanager.ServerManager) */ public void stopServer(String serverName) throws IOException { Server server = manager.getServer(serverName); if (server.isRunning()) manager.stopServer(serverName); } /** * Stop a group of servers. Any error stopping a server will logged and then the next one in the list will be tried. * * @param servers the names of the servers to be stopped * @see ASTestConfig#stopServer(String) */ public void stopServers(String ... servers) { for (String server : servers) { try { stopServer(server); } catch (IOException e) { System.err.println("Unable to stop server " + server); } } } public ServerManager getServerManager() { return manager; } /** * Configure a target AS to start with a non-default set of bindings * * @param serverName the server whose bindings are being configured * @throws TransformerException error parsing the server bindings xml file * @throws IOException error whilst locating the bindings file in the file system * @throws SAXException error parsing the server bindings xml file * @throws ParserConfigurationException error parsing the server bindings xml file */ public void configureServerBinding(String serverName) throws TransformerException, IOException, SAXException, ParserConfigurationException { Server server = manager.getServer(serverName); String configHome = getProductDir(); String mbeanServiceFile = getServerPath(serverName) + "conf/jboss-service.xml"; String bindingName = server.getSysProperty("server.binding.name"); String bindingFile = server.getSysProperty("server.binding.location"); if (bindingFile == null) return; bindingFile = configHome + bindingFile; // if bindingName is set then it is safe to check that the AS is up via the Naming service port // BTW the AS5 team has changed the behavior of the naming service port - it is opened before // all the services have been configured so any target deployments may not have been initialised // when the server is declared as running. Instead we force the server to use a web server port to // determine if the AS is running. if (bindingName == null) return; // bindingName = ServerBindingConfig.DEFAULT_BINDING; // else // server.setHasWebServer(true); ServerBindingConfig.setBinding(mbeanServiceFile, bindingName, bindingFile); server.setRmiPort(ServerBindingConfig.lookupRmiPort(bindingFile, bindingName, server.getRmiPort())); server.setHttpPort(ServerBindingConfig.lookupHttpPort(bindingFile, bindingName, server.getHttpPort())); System.out.println("Using: " + Context.PROVIDER_URL + " = jnp://"+ server.getHost() + ':' + server.getRmiPort() + " and http port " + server.getHttpPort()); } }