blob: 8b366a866e593b651bb9fabb9735dca69c924fbb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.jmeter.protocol.java.sampler;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.samplers.AbstractSampler;
import org.apache.jmeter.samplers.Entry;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestListener;
import org.apache.jmeter.testelement.property.TestElementProperty;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
/**
* A sampler for executing custom Commons Chain Commands
*
* @author Edgar Poce
*/
public class ChainSampler extends AbstractSampler implements TestListener
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 3618986663356151348L;
/**
* chainCtx key
*/
public static final String CHAINS_CONTEXT = "chainCtx";
/**
* The Command instance used by this sampler to actually perform the sample.
*/
private transient Command command = null;
/**
* Logging
*/
private static transient Logger log = LoggingManager.getLoggerForClass();
/**
* Set used to register all active JavaSamplers. This is used so that the
* samplers can be notified when the test ends.
*/
private static Set allSamplers = new HashSet();
/**
* Create a JavaSampler.
*/
public ChainSampler()
{
setArguments(new Arguments());
synchronized (allSamplers)
{
allSamplers.add(this);
}
}
/**
* Set the arguments (parameters) for the JavaSamplerClient to be executed
* with.
*
* @param args
* the new arguments. These replace any existing arguments.
*/
public void setArguments(Arguments args)
{
setProperty(new TestElementProperty(JavaSampler.ARGUMENTS, args));
}
/**
* Get the arguments (parameters) for the JavaSamplerClient to be executed
* with.
*
* @return the arguments
*/
public Arguments getArguments()
{
return (Arguments) getProperty(JavaSampler.ARGUMENTS).getObjectValue();
}
/**
* Releases Command Client.
*/
private void releaseClient()
{
this.command = null;
}
/**
* Sets the Classname attribute of the JavaConfig object
*
* @param classname
* the new Classname value
*/
public void setClassname(String classname)
{
setProperty(JavaSampler.CLASSNAME, classname);
}
/**
* Gets the Classname attribute of the JavaConfig object
*
* @return the Classname value
*/
public String getClassname()
{
return getPropertyAsString(JavaSampler.CLASSNAME);
}
/**
* Performs a test sample.
*
* The <code>sample()</code> method retrieves the reference to the command
* and calls its <code>execute()</code> method.
*
* @param entry
* the Entry for this sample
* @return test SampleResult
*/
public SampleResult sample(Entry entry)
{
SampleResult results = new SampleResult();
try
{
if (command == null)
{
log.debug(whoAmI() + "Creating Command");
createCommand();
}
updateCommand();
results.setSampleLabel(this.getName());
Context ctx = new JMeterContextAdapter(getThreadContext());
results.sampleStart();
command.execute(ctx);
results.sampleEnd();
results.setSuccessful(true);
} catch (Exception e)
{
results.setSuccessful(false);
log.error("Unable to run test", e);
}
return results;
}
/**
* Returns reference to <code>Command</code>.
*
* @return Command reference.
*/
private Command createCommand() throws Exception
{
Class javaClass = Class.forName(getClassname().trim(), false, Thread
.currentThread().getContextClassLoader());
command = (Command) javaClass.newInstance();
if (log.isDebugEnabled())
{
log.debug(whoAmI() + "\tCreated:\t" + getClassname() + "@"
+ Integer.toHexString(command.hashCode()));
}
return command;
}
/**
* Updates the command attributes
*
* @throws Exception
*/
private void updateCommand() throws Exception
{
Map descrip = BeanUtils.describe(command);
Iterator iter = descrip.keySet().iterator();
while (iter.hasNext())
{
String key = (String) iter.next();
Object value = this.getArguments().getArgumentsAsMap().get(key);
if (value != null && value.toString().length() > 0)
{
BeanUtils.setProperty(command, key, value);
}
}
}
/**
* Retrieves reference to JavaSamplerClient.
*
* Convience method used to check for null reference without actually
* creating a JavaSamplerClient
*
* @return reference to JavaSamplerClient NOTUSED private JavaSamplerClient
* retrieveJavaClient() { return javaClient; }
*/
/**
* Generate a String identifier of this instance for debugging purposes.
*
* @return a String identifier for this sampler instance
*/
private String whoAmI()
{
StringBuffer sb = new StringBuffer();
sb.append(Thread.currentThread().getName());
sb.append("@");
sb.append(Integer.toHexString(hashCode()));
return sb.toString();
}
// TestListener implementation
/* Implements TestListener.testStarted() */
public void testStarted()
{
log.debug(whoAmI() + "\ttestStarted");
}
/* Implements TestListener.testStarted(String) */
public void testStarted(String host)
{
log.debug(whoAmI() + "\ttestStarted(" + host + ")");
}
/**
* Method called at the end of the test. This is called only on one instance
* of ChainSampler. This method will loop through all of the other samplers
* which have been registered (automatically in the constructor) and notify
* them that the test has ended, allowing the ChainSamplerClients to
* cleanup.
*/
public void testEnded()
{
log.debug(whoAmI() + "\ttestEnded");
synchronized (allSamplers)
{
Iterator i = allSamplers.iterator();
while (i.hasNext())
{
ChainSampler sampler = (ChainSampler) i.next();
sampler.releaseClient();
i.remove();
}
}
}
/* Implements TestListener.testEnded(String) */
public void testEnded(String host)
{
testEnded();
}
/* Implements TestListener.testIterationStart(LoopIterationEvent) */
public void testIterationStart(LoopIterationEvent event)
{
}
}