/*
* 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());
}
}