- Redesigned the perf plugin

- Added the cpu sampler for linux using vmstat (no summary as of the moment).

git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@416542 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrian T. Co 2006-06-23 01:53:48 +00:00
parent ab027d0867
commit f1c6e4c663
34 changed files with 1825 additions and 2097 deletions

View File

@ -1,7 +1,6 @@
package org.apache.activemq.maven; /**
*
/* * Copyright 2005-2006 The Apache Software Foundation
* Copyright 2001-2005 The Apache Software Foundation.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -15,13 +14,18 @@ package org.apache.activemq.maven;
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.maven;
import org.apache.activemq.tool.JmsConsumerSystem; import org.apache.activemq.tool.JmsConsumerSystem;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoExecutionException;
import javax.jms.JMSException; import java.util.Properties;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
/** /**
* Goal which touches a timestamp file. * Goal which touches a timestamp file.
@ -29,211 +33,40 @@ import javax.jms.JMSException;
* @goal consumer * @goal consumer
* @phase process-sources * @phase process-sources
*/ */
public class ConsumerMojo public class ConsumerMojo extends AbstractMojo {
extends AbstractMojo {
/** private String[] validPrefix = {
* @parameter expression="${sampler.duration}" default-value="60000" "sysTest.",
* @required "factory.",
*/ "consumer.",
private String duration; "tpSampler.",
"cpuSampler."
/**
* @parameter expression="${sampler.interval}" default-value="1000"
* @required
*/
private String interval;
/**
* @parameter expression="${sampler.rampUpTime}" default-value="10000"
* @required
*/
private String rampUpTime;
/**
* @parameter expression="${sampler.rampDownTime}" default-value="10000"
* @required
*/
private String rampDownTime;
/**
* @parameter expression="${consumer.spiClass}" default-value="org.apache.activemq.tool.spi.ActiveMQPojoSPI"
* @required
*/
private String spiClass;
/**
* @parameter expression="${consumer.sessTransacted}" default-value="false"
* @required
*/
private String sessTransacted;
/**
* @parameter expression="${consumer.sessAckMode}" default-value="autoAck"
* @required
*/
private String sessAckMode;
/**
* @parameter expression="${consumer.destName}" default-value="topic://TEST.PERFORMANCE.FOO.BAR"
* @required
*/
private String destName;
/**
* @parameter expression="${consumer.destCount}" default-value="1"
* @required
*/
private String destCount;
/**
* @parameter expression="${consumer.destComposite}" default-value="false"
* @required
*/
private String destComposite;
/**
* @parameter expression="${consumer.durable}" default-value="false"
* @required
*/
private String durable;
/**
* @parameter expression="${consumer.asyncRecv}" default-value="true"
* @required
*/
private String asyncRecv;
/**
* @parameter expression="${consumer.recvCount}" default-value="1000000"
* @required
*/
private String recvCount;
/*
* @parameter expression="${consumer.recvDuration}" default-value="60000"
* @required
private String recvDuration;
*/
/**
* @parameter expression="${consumer.recvType}" default-value="time"
* @required
*/
private String recvType;
/**
* @parameter expression="${factory.brokerUrl}" default-value="tcp://localhost:61616"
* @required
*/
private String brokerUrl;
/**
* @parameter expression="${factory.optimAck}" default-value="true"
* @required
*/
private String optimAck;
/**
* @parameter expression="${factory.optimDispatch}" default-value="true"
* @required
*/
private String optimDispatch;
/**
* @parameter expression="${factory.prefetchQueue}" default-value="5000"
* @required
*/
private String prefetchQueue;
/**
* @parameter expression="${factory.prefetchTopic}" default-value="5000"
* @required
*/
private String prefetchTopic;
/**
* @parameter expression="${factory.useRetroactive}" default-value="false"
* @required
*/
private String useRetroactive;
/**
* @parameter expression="${sysTest.numClients}" default-value="1"
* @required
*/
private String numClients;
/**
* @parameter expression="${sysTest.totalDests}" default-value="1"
* @required
*/
private String totalDests;
/**
* @parameter expression="${sysTest.destDistro}" default-value="all"
* @required
*/
private String destDistro;
/**
* @parameter expression="${sysTest.reportDirectory}" default-value="${project.build.directory}/test-perf"
* @required
*/
private String reportDirectory;
/**
* @parameter expression="${sysTest.reportType}" default-value="xml"
* @required
*/
private String reportType;
public void execute()
throws MojoExecutionException {
try {
JmsConsumerSystem.main(createArgument());
} catch (JMSException e) {
throw new MojoExecutionException(e.getMessage());
}
}
public String[] createArgument() {
String[] options = {
"sampler.duration=" + duration,
"sampler.interval=" + interval,
"sampler.rampUpTime=" + rampUpTime,
"sampler.rampDownTime=" + rampDownTime,
"consumer.spiClass=" + spiClass,
"consumer.sessTransacted=" + sessTransacted,
"consumer.sessAckMode=" + sessAckMode,
"consumer.destName=" + destName,
"consumer.destCount=" + destCount,
"consumer.destComposite=" + destComposite,
"consumer.durable=" + durable,
"consumer.asyncRecv=" + asyncRecv,
"consumer.recvCount=" + recvCount,
"consumer.recvDuration=" + duration,
"consumer.recvType=" + recvType,
"factory.brokerUrl=" + brokerUrl,
"factory.optimAck=" + optimAck,
"factory.optimDispatch=" + optimDispatch,
"factory.prefetchQueue=" + prefetchQueue,
"factory.prefetchTopic=" + prefetchTopic,
"factory.useRetroactive=" + useRetroactive,
"sysTest.numClients=" + numClients,
"sysTest.totalDests=" + totalDests,
"sysTest.destDistro=" + destDistro,
"sysTest.reportDirectory=" + reportDirectory,
"sysTest.reportType=" + reportType
}; };
return options; public void execute() throws MojoExecutionException {
JmsConsumerSystem.main(createArgument());
}
protected String[] createArgument() {
List args = new ArrayList();
Properties sysProps = System.getProperties();
Set keys = new HashSet(sysProps.keySet());
for (Iterator i=keys.iterator(); i.hasNext();) {
String key = (String)i.next();
if (isRecognizedProperty(key)) {
args.add(key + "=" + sysProps.remove(key));
}
}
return (String[])args.toArray(new String[0]);
}
protected boolean isRecognizedProperty(String key) {
for (int j=0; j<validPrefix.length; j++) {
if (key.startsWith(validPrefix[j])) {
return true;
}
}
return false;
} }
} }

View File

@ -1,11 +1,6 @@
package org.apache.activemq.maven; /**
*
import org.apache.activemq.tool.JmsProducerSystem; * Copyright 2005-2006 The Apache Software Foundation
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
/*
* Copyright 2001-2005 The Apache Software Foundation.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,7 +14,18 @@ import org.apache.maven.plugin.MojoExecutionException;
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.maven;
import org.apache.activemq.tool.JmsProducerSystem;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
/** /**
* Goal which touches a timestamp file. * Goal which touches a timestamp file.
@ -27,180 +33,40 @@ import org.apache.maven.plugin.MojoExecutionException;
* @goal producer * @goal producer
* @phase process * @phase process
*/ */
public class ProducerMojo public class ProducerMojo extends AbstractMojo {
extends AbstractMojo {
/** private String[] validPrefix = {
* @parameter expression="${sampler.duration}" default-value="60000" "sysTest.",
* @required "factory.",
*/ "producer.",
private String duration; "tpSampler.",
"cpuSampler."
/** };
* @parameter expression="${sampler.interval}" default-value="1000"
* @required
*/
private String interval;
/**
* @parameter expression="${sampler.rampUpTime}" default-value="10000"
* @required
*/
private String rampUpTime;
/**
* @parameter expression="${sampler.rampDownTime}" default-value="10000"
* @required
*/
private String rampDownTime;
/**
* @parameter expression="${producer.spiClass}" default-value="org.apache.activemq.tool.spi.ActiveMQPojoSPI"
* @required
*/
private String spiClass;
/**
* @parameter expression="${producer.sessTransacted}" default-value="false"
* @required
*/
private String sessTransacted;
/**
* @parameter expression="${producer.sessAckMode}" default-value="autoAck"
* @required
*/
private String sessAckMode;
/**
* @parameter expression="${producer.destName}" default-value="topic://TEST.PERFORMANCE.FOO.BAR"
* @required
*/
private String destName;
/**
* @parameter expression="${producer.destCount}" default-value="1"
* @required
*/
private String destCount;
/**
* @parameter expression="${producer.destComposite}" default-value="false"
* @required
*/
private String destComposite;
/**
* @parameter expression="${producer.deliveryMode}" default-value="nonpersistent"
* @required
*/
private String deliveryMode;
/**
* @parameter expression="${producer.messageSize}" default-value="1024"
* @required
*/
private String messageSize;
/**
* @parameter expression="${producer.sendCount}" default-value="1000000"
* @required
*/
private String sendCount;
/*
* @parameter expression="${producer.sendDuration}" default-value="60000"
* @required
private String sendDuration;
*/
/**
* @parameter expression="${producer.sendType}" default-value="time"
* @required
*/
private String sendType;
/**
* @parameter expression="${factory.brokerUrl}" default-value="tcp://localhost:61616"
* @required
*/
private String brokerUrl;
/**
* @parameter expression="${factory.asyncSend}" default-value="true"
* @required
*/
private String asyncSend;
/**
* @parameter expression="${sysTest.numClients}" default-value="1"
* @required
*/
private String numClients;
/**
* @parameter expression="${sysTest.totalDests}" default-value="1"
* @required
*/
private String totalDests;
/**
* @parameter expression="${sysTest.destDistro}" default-value="all"
* @required
*/
private String destDistro;
/**
* @parameter expression="${sysTest.reportDirectory}" default-value="${project.build.directory}/test-perf"
* @required
*/
private String reportDirectory;
/**
* @parameter expression="${sysTest.reportType}" default-value="xml"
* @required
*/
private String reportType;
public void execute()
throws MojoExecutionException {
public void execute() throws MojoExecutionException {
JmsProducerSystem.main(createArgument()); JmsProducerSystem.main(createArgument());
} }
public String[] createArgument() { protected String[] createArgument() {
List args = new ArrayList();
Properties sysProps = System.getProperties();
Set keys = new HashSet(sysProps.keySet());
String[] options = { for (Iterator i=keys.iterator(); i.hasNext();) {
"sampler.duration=" + duration, String key = (String)i.next();
"sampler.interval=" + interval, if (isRecognizedProperty(key)) {
"sampler.rampUpTime=" + rampUpTime, args.add(key + "=" + sysProps.remove(key));
"sampler.rampDownTime=" + rampDownTime, }
}
return (String[])args.toArray(new String[0]);
}
"producer.spiClass=" + spiClass, protected boolean isRecognizedProperty(String key) {
"producer.sessTransacted=" + sessTransacted, for (int j=0; j<validPrefix.length; j++) {
"producer.sessAckMode=" + sessAckMode, if (key.startsWith(validPrefix[j])) {
"producer.destName=" + destName, return true;
"producer.destCount=" + destCount, }
"producer.destComposite=" + destComposite, }
return false;
"producer.deliveryMode="+deliveryMode,
"producer.messageSize="+messageSize,
"producer.sendCount="+sendCount,
"producer.sendDuration="+duration,
"producer.sendType="+sendType,
"factory.brokerUrl="+brokerUrl,
"factory.asyncSend="+asyncSend,
"sysTest.numClients=" + numClients,
"sysTest.totalDests=" + totalDests,
"sysTest.destDistro=" + destDistro,
"sysTest.reportDirectory=" + reportDirectory,
"sysTest.reportType=" + reportType
};
return options;
} }
} }

View File

@ -1,7 +1,6 @@
package org.apache.activemq.maven; /**
*
/* * Copyright 2005-2006 The Apache Software Foundation
* Copyright 2001-2005 The Apache Software Foundation.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -15,6 +14,7 @@ package org.apache.activemq.maven;
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.maven;
import org.apache.activemq.console.Main; import org.apache.activemq.console.Main;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojo;
@ -33,8 +33,7 @@ import java.nio.channels.FileChannel;
* @goal broker * @goal broker
* @phase process-sources * @phase process-sources
*/ */
public class ServerMojo public class ServerMojo extends AbstractMojo {
extends AbstractMojo {
/** /**
* Location of the output directory. Defaults to target. * Location of the output directory. Defaults to target.
* *
@ -83,7 +82,6 @@ public class ServerMojo
out.mkdirs(); out.mkdirs();
} }
String[] args = new String[2]; String[] args = new String[2];
if (url != null) { if (url != null) {
args[0] = "start"; args[0] = "start";

View File

@ -0,0 +1,150 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool;
import org.apache.activemq.tool.properties.JmsClientProperties;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;
import javax.jms.Session;
import javax.jms.JMSException;
import javax.jms.Destination;
public abstract class AbstractJmsClient {
protected ConnectionFactory factory;
protected Connection jmsConnection;
protected Session jmsSession;
protected int destCount = 1, destIndex = 0;
protected String clientName = "";
public AbstractJmsClient(ConnectionFactory factory) {
this.factory = factory;
}
abstract public JmsClientProperties getClient();
abstract public void setClient(JmsClientProperties client);
public ConnectionFactory getFactory() {
return factory;
}
public void setFactory(ConnectionFactory factory) {
this.factory = factory;
}
public int getDestCount() {
return destCount;
}
public void setDestCount(int destCount) {
this.destCount = destCount;
}
public int getDestIndex() {
return destIndex;
}
public void setDestIndex(int destIndex) {
this.destIndex = destIndex;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public Connection getConnection() throws JMSException {
if (jmsConnection == null) {
jmsConnection = factory.createConnection();
}
return jmsConnection;
}
public Session getSession() throws JMSException {
if (jmsSession == null) {
int ackMode;
if (getClient().getSessAckMode().equalsIgnoreCase(JmsClientProperties.SESSION_AUTO_ACKNOWLEDGE)) {
ackMode = Session.AUTO_ACKNOWLEDGE;
} else if (getClient().getSessAckMode().equalsIgnoreCase(JmsClientProperties.SESSION_CLIENT_ACKNOWLEDGE)) {
ackMode = Session.CLIENT_ACKNOWLEDGE;
} else if (getClient().getSessAckMode().equalsIgnoreCase(JmsClientProperties.SESSION_DUPS_OK_ACKNOWLEDGE)) {
ackMode = Session.DUPS_OK_ACKNOWLEDGE;
} else if (getClient().getSessAckMode().equalsIgnoreCase(JmsClientProperties.SESSION_TRANSACTED)) {
ackMode = Session.SESSION_TRANSACTED;
} else {
ackMode = Session.AUTO_ACKNOWLEDGE;
}
jmsSession = getConnection().createSession(getClient().isSessTransacted(), ackMode);
}
return jmsSession;
}
public Destination[] createDestination(int destIndex, int destCount) throws JMSException {
if (getClient().isDestComposite()) {
return new Destination[] {createCompositeDestination(getClient().getDestName(), destIndex, destCount)};
} else {
Destination[] dest = new Destination[destCount];
for (int i=0; i<destCount; i++) {
dest[i] = createDestination(getClient().getDestName() + "." + (destIndex + i));
}
return dest;
}
}
public Destination createCompositeDestination(int destIndex, int destCount) throws JMSException {
return createCompositeDestination(getClient().getDestName(), destIndex, destCount);
}
protected Destination createCompositeDestination(String name, int destIndex, int destCount) throws JMSException {
String compDestName;
String simpleName;
if (name.startsWith("queue://")) {
simpleName = name.substring("queue://".length());
} else if (name.startsWith("topic://")) {
simpleName = name.substring("topic://".length());
} else {
simpleName = name;
}
int i;
compDestName = name + "." + destIndex + ","; // First destination
for (i=1; i<destCount-1; i++) {
compDestName += (simpleName + "." + (destIndex + i) +",");
}
compDestName += (simpleName + "." + (destIndex + i)); // Last destination (minus the comma)
return createDestination(compDestName);
}
protected Destination createDestination(String name) throws JMSException {
if (name.startsWith("queue://")) {
return getSession().createQueue(name.substring("queue://".length()));
} else if (name.startsWith("topic://")) {
return getSession().createTopic(name.substring("topic://".length()));
} else {
return getSession().createTopic(name);
}
}
}

View File

@ -0,0 +1,210 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.activemq.tool.sampler.ThroughputSamplerTask;
import org.apache.activemq.tool.sampler.CpuSamplerTask;
import org.apache.activemq.tool.reports.PerformanceReportWriter;
import org.apache.activemq.tool.reports.XmlFilePerfReportWriter;
import org.apache.activemq.tool.reports.VerbosePerfReportWriter;
import org.apache.activemq.tool.properties.JmsClientSystemProperties;
import org.apache.activemq.tool.properties.AbstractObjectProperties;
import org.apache.activemq.tool.properties.JmsFactoryProperties;
import org.apache.activemq.tool.properties.ReflectionUtil;
import org.apache.activemq.tool.properties.JmsClientProperties;
import org.apache.activemq.tool.spi.SPIConnectionFactory;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import java.util.Properties;
import java.io.IOException;
public abstract class AbstractJmsClientSystem extends AbstractObjectProperties {
private static final Log log = LogFactory.getLog(AbstractJmsClientSystem.class);
private int clientDestIndex, clientDestCount;
protected ThreadGroup clientThreadGroup;
protected ConnectionFactory jmsConnFactory;
// Properties
protected JmsFactoryProperties factory = new JmsFactoryProperties();
protected ThroughputSamplerTask tpSampler = new ThroughputSamplerTask();
protected CpuSamplerTask cpuSampler = new CpuSamplerTask();
public void runSystemTest() throws JMSException {
// Create connection factory
jmsConnFactory = loadJmsFactory(getSysTest().getSpiClass(), factory.getFactorySettings());
// Create performance sampler
PerformanceReportWriter writer = createPerfWriter();
tpSampler.setPerfReportWriter(writer);
cpuSampler.setPerfReportWriter(writer);
writer.openReportWriter();
writer.writeProperties("jvmSettings", System.getProperties());
writer.writeProperties("testSystemSettings", ReflectionUtil.retrieveObjectProperties(getSysTest()));
writer.writeProperties("jmsFactorySettings", ReflectionUtil.retrieveObjectProperties(jmsConnFactory));
writer.writeProperties("jmsClientSettings", ReflectionUtil.retrieveObjectProperties(getJmsClientProperties()));
writer.writeProperties("tpSamplerSettings", ReflectionUtil.retrieveObjectProperties(tpSampler));
writer.writeProperties("cpuSamplerSettings", ReflectionUtil.retrieveObjectProperties(cpuSampler));
clientThreadGroup = new ThreadGroup(getSysTest().getClientPrefix() + " Thread Group");
for (int i=0; i<getSysTest().getNumClients(); i++) {
distributeDestinations(getSysTest().getDestDistro(), i, getSysTest().getNumClients(), getSysTest().getTotalDests());
final String clientName = getSysTest().getClientPrefix() + i;
final int clientDestIndex = this.clientDestIndex;
final int clientDestCount = this.clientDestCount;
Thread t = new Thread(clientThreadGroup, new Runnable() {
public void run() {
runJmsClient(clientName, clientDestIndex, clientDestCount);
}
});
t.setName(getSysTest().getClientPrefix() + i + " Thread");
t.start();
}
// Run samplers
if (getSysTest().getSamplers().indexOf(JmsClientSystemProperties.SAMPLER_TP) > -1) {
tpSampler.startSampler();
}
if (getSysTest().getSamplers().indexOf(JmsClientSystemProperties.SAMPLER_CPU) > -1) {
try {
cpuSampler.createPlugin();
cpuSampler.startSampler();
} catch (IOException e) {
log.warn("Unable to start CPU sampler plugin. Reason: " + e.getMessage());
}
}
tpSampler.waitUntilDone();
cpuSampler.waitUntilDone();
writer.closeReportWriter();
}
public ThroughputSamplerTask getTpSampler() {
return tpSampler;
}
public void setTpSampler(ThroughputSamplerTask tpSampler) {
this.tpSampler = tpSampler;
}
public CpuSamplerTask getCpuSampler() {
return cpuSampler;
}
public void setCpuSampler(CpuSamplerTask cpuSampler) {
this.cpuSampler = cpuSampler;
}
public JmsFactoryProperties getFactory() {
return factory;
}
public void setFactory(JmsFactoryProperties factory) {
this.factory = factory;
}
public abstract JmsClientSystemProperties getSysTest();
public abstract void setSysTest(JmsClientSystemProperties sysTestProps);
public abstract JmsClientProperties getJmsClientProperties();
protected PerformanceReportWriter createPerfWriter() {
if (getSysTest().getReportType().equalsIgnoreCase(JmsClientSystemProperties.REPORT_XML_FILE)) {
String reportName;
if ((reportName = getSysTest().getReportName()) == null) {
reportName = getSysTest().getClientPrefix() + "_" +
"numClients" + getSysTest().getNumClients() + "_" +
"numDests" + getSysTest().getTotalDests() + "_" +
getSysTest().getDestDistro();
}
return new XmlFilePerfReportWriter(getSysTest().getReportDir(), reportName);
} else if (getSysTest().getReportType().equalsIgnoreCase(JmsClientSystemProperties.REPORT_VERBOSE)) {
return new VerbosePerfReportWriter();
} else {
// Use verbose if unknown report type
return new VerbosePerfReportWriter();
}
}
protected void distributeDestinations(String distroType, int clientIndex, int numClients, int numDests) {
if (distroType.equalsIgnoreCase(JmsClientSystemProperties.DEST_DISTRO_ALL)) {
clientDestCount = numDests;
clientDestIndex = 0;
} else if (distroType.equalsIgnoreCase(JmsClientSystemProperties.DEST_DISTRO_EQUAL)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
clientDestCount = destPerClient;
clientDestIndex = destPerClient * clientIndex;
// If there are more clients than destinations, share destinations per client
} else {
clientDestCount = 1; // At most one destination per client
clientDestIndex = clientIndex % numDests;
}
} else if (distroType.equalsIgnoreCase(JmsClientSystemProperties.DEST_DISTRO_DIVIDE)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
int remain = numDests % numClients;
int nextIndex;
if (clientIndex < remain) {
destPerClient++;
nextIndex = clientIndex * destPerClient;
} else {
nextIndex = (clientIndex * destPerClient) + remain;
}
clientDestCount = destPerClient;
clientDestIndex = nextIndex;
// If there are more clients than destinations, share destinations per client
} else {
clientDestCount = 1; // At most one destination per client
clientDestIndex = clientIndex % numDests;
}
// Send to all for unknown behavior
} else {
log.warn("Unknown destination distribution type: " + distroType);
clientDestCount = numDests;
clientDestIndex = 0;
}
}
protected ConnectionFactory loadJmsFactory(String spiClass, Properties factorySettings) throws JMSException {
try {
Class spi = Class.forName(spiClass);
SPIConnectionFactory spiFactory = (SPIConnectionFactory)spi.newInstance();
ConnectionFactory jmsFactory = spiFactory.createConnectionFactory(factorySettings);
log.info("Created: " + jmsFactory.getClass().getName() + " using SPIConnectionFactory: " + spiFactory.getClass().getName());
return jmsFactory;
} catch (Exception e) {
e.printStackTrace();
throw new JMSException(e.getMessage());
}
}
protected abstract void runJmsClient(String clientName, int clientDestIndex, int clientDestCount);
}

View File

@ -16,26 +16,23 @@
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool;
import org.apache.activemq.tool.sampler.MeasurableClient;
import javax.jms.ConnectionFactory;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLong; import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicLong;
public class JmsPerformanceSupport extends JmsClientSupport implements PerfMeasurable { public abstract class AbstractJmsMeasurableClient extends AbstractJmsClient implements MeasurableClient {
protected AtomicLong throughput = new AtomicLong(0); protected AtomicLong throughput = new AtomicLong(0);
protected PerfEventListener listener = null;
protected String clientName = null; public AbstractJmsMeasurableClient( ConnectionFactory factory) {
super( factory);
}
public void reset() { public void reset() {
setThroughput(0); setThroughput(0);
} }
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public long getThroughput() { public long getThroughput() {
return throughput.get(); return throughput.get();
} }
@ -51,12 +48,4 @@ public class JmsPerformanceSupport extends JmsClientSupport implements PerfMeasu
public void incThroughput(long val) { public void incThroughput(long val) {
throughput.addAndGet(val); throughput.addAndGet(val);
} }
public void setPerfEventListener(PerfEventListener listener) {
this.listener = listener;
}
public PerfEventListener getPerfEventListener() {
return listener;
}
} }

View File

@ -1,212 +0,0 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.jms.ConnectionFactory;
import javax.jms.Session;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import java.util.Properties;
public class JmsClientSupport extends JmsFactorySupport {
private static final Log log = LogFactory.getLog(JmsClientSupport.class);
public static final String DEFAULT_SPI_CLASS = "org.apache.activemq.tool.spi.ActiveMQPojoSPI";
private static final String PREFIX_CONFIG_CLIENT = "client.";
public static final String SESSION_AUTO_ACKNOWLEDGE = "autoAck";
public static final String SESSION_CLIENT_ACKNOWLEDGE = "clientAck";
public static final String SESSION_DUPS_OK_ACKNOWLEDGE = "dupsAck";
public static final String SESSION_TRANSACTED = "transacted";
protected Properties clientSettings = new Properties();
protected Connection jmsConnection;
protected Session jmsSession;
// Client settings
protected String spiClass = DEFAULT_SPI_CLASS;
protected boolean sessTransacted = false;
protected String sessAckMode = SESSION_AUTO_ACKNOWLEDGE;
protected String destName = "TEST.FOO";
protected int destCount = 1;
protected int destIndex = 0;
protected boolean destComposite = false;
public ConnectionFactory createConnectionFactory() throws JMSException {
return super.createConnectionFactory(getSpiClass());
}
public Connection getConnection() throws JMSException {
if (jmsConnection == null) {
jmsConnection = createConnectionFactory().createConnection();
}
return jmsConnection;
}
public Session getSession() throws JMSException {
if (jmsSession == null) {
int ackMode;
if (getSessAckMode().equalsIgnoreCase(SESSION_AUTO_ACKNOWLEDGE)) {
ackMode = Session.AUTO_ACKNOWLEDGE;
} else if (getSessAckMode().equalsIgnoreCase(SESSION_CLIENT_ACKNOWLEDGE)) {
ackMode = Session.CLIENT_ACKNOWLEDGE;
} else if (getSessAckMode().equalsIgnoreCase(SESSION_DUPS_OK_ACKNOWLEDGE)) {
ackMode = Session.DUPS_OK_ACKNOWLEDGE;
} else if (getSessAckMode().equalsIgnoreCase(SESSION_TRANSACTED)) {
ackMode = Session.SESSION_TRANSACTED;
} else {
ackMode = Session.AUTO_ACKNOWLEDGE;
}
jmsSession = getConnection().createSession(isSessTransacted(), ackMode);
}
return jmsSession;
}
public Destination[] createDestination() throws JMSException {
if (isDestComposite()) {
return new Destination[] {createCompositeDestination(getDestName(), getDestCount())};
} else {
Destination[] dest = new Destination[getDestCount()];
for (int i=0; i<getDestCount(); i++) {
dest[i] = createDestination(getDestName() + "." + (getDestIndex() + i));
}
return dest;
}
}
public Destination createDestination(String name) throws JMSException {
if (name.startsWith("queue://")) {
return getSession().createQueue(name.substring("queue://".length()));
} else if (name.startsWith("topic://")) {
return getSession().createTopic(name.substring("topic://".length()));
} else {
return getSession().createTopic(name);
}
}
public Destination createCompositeDestination(String name, int count) throws JMSException {
String compDestName = "";
String simpleName;
if (name.startsWith("queue://")) {
simpleName = name.substring("queue://".length());
} else if (name.startsWith("topic://")) {
simpleName = name.substring("topic://".length());
} else {
simpleName = name;
}
int i;
compDestName = name + ".0,"; // First destination
for (i=1; i<count-1; i++) {
compDestName += (simpleName + "." + i +",");
}
compDestName += (simpleName + "." + i); // Last destination (minus the comma)
return createDestination(compDestName);
}
public String getSpiClass() {
return spiClass;
}
public void setSpiClass(String spiClass) {
this.spiClass = spiClass;
}
public boolean isSessTransacted() {
return sessTransacted;
}
public void setSessTransacted(boolean sessTransacted) {
this.sessTransacted = sessTransacted;
}
public String getSessAckMode() {
return sessAckMode;
}
public void setSessAckMode(String sessAckMode) {
this.sessAckMode = sessAckMode;
}
public String getDestName() {
return destName;
}
public void setDestName(String destName) {
this.destName = destName;
}
public int getDestCount() {
return destCount;
}
public void setDestCount(int destCount) {
this.destCount = destCount;
}
public int getDestIndex() {
return destIndex;
}
public void setDestIndex(int destIndex) {
this.destIndex = destIndex;
}
public boolean isDestComposite() {
return destComposite;
}
public void setDestComposite(boolean destComposite) {
this.destComposite = destComposite;
}
public Properties getClientSettings() {
return clientSettings;
}
public void setClientSettings(Properties clientSettings) {
this.clientSettings = clientSettings;
ReflectionUtil.configureClass(this, clientSettings);
}
public Properties getSettings() {
Properties allSettings = new Properties(clientSettings);
allSettings.putAll(super.getSettings());
return allSettings;
}
public void setSettings(Properties settings) {
super.setSettings(settings);
ReflectionUtil.configureClass(this, clientSettings);
}
public void setProperty(String key, String value) {
if (key.startsWith(PREFIX_CONFIG_CLIENT)) {
clientSettings.setProperty(key, value);
} else {
super.setProperty(key, value);
}
}
}

View File

@ -1,283 +0,0 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.activemq.tool.reports.VerbosePerfReportWriter;
import org.apache.activemq.tool.reports.PerformanceReportWriter;
import org.apache.activemq.tool.reports.XmlFilePerfReportWriter;
import java.util.Properties;
import java.util.Iterator;
public abstract class JmsClientSystemSupport {
private static final Log log = LogFactory.getLog(JmsClientSystemSupport.class);
public static final String PREFIX_CONFIG_SYSTEM_TEST = "sysTest.";
public static final String DEST_DISTRO_ALL = "all"; // Each client will send/receive to all destination;
public static final String DEST_DISTRO_EQUAL = "equal"; // Equally divide the number of destinations to the number of clients
public static final String DEST_DISTRO_DIVIDE = "divide"; // Divide the destination among the clients, even if some have more destination than others
public static final String REPORT_VERBOSE = "verbose";
public static final String REPORT_XML_FILE = "xml";
protected Properties sysTestSettings = new Properties();
protected Properties samplerSettings = new Properties();
protected Properties jmsClientSettings = new Properties();
protected ThreadGroup clientThreadGroup;
protected PerfMeasurementTool performanceSampler;
protected String reportType = REPORT_XML_FILE;
protected String reportDirectory = "./";
protected String reportName = null;
protected String clientName = null;
protected int numClients = 1;
protected int totalDests = 1;
protected String destDistro = DEST_DISTRO_ALL;
public void runSystemTest() {
// Create performance sampler
performanceSampler = new PerfMeasurementTool();
performanceSampler.setSamplerSettings(samplerSettings);
PerformanceReportWriter writer = createPerfWriter();
performanceSampler.setPerfWriter(writer);
writer.openReportWriter();
writer.writeProperties("testProperties", getSettings());
clientThreadGroup = new ThreadGroup(getThreadGroupName());
for (int i=0; i<getNumClients(); i++) {
final Properties clientSettings = new Properties();
clientSettings.putAll(getJmsClientSettings());
distributeDestinations(getDestDistro(), i, getNumClients(), getTotalDests(), clientSettings);
final String clientName = getClientName() + i;
Thread t = new Thread(clientThreadGroup, new Runnable() {
public void run() {
runJmsClient(clientName, clientSettings);
}
});
t.setName(getThreadName() + i);
t.start();
}
performanceSampler.startSampler();
performanceSampler.waitForSamplerToFinish(0);
writer.closeReportWriter();
}
public PerfMeasurementTool getPerformanceSampler() {
return performanceSampler;
}
public void setPerformanceSampler(PerfMeasurementTool performanceSampler) {
this.performanceSampler = performanceSampler;
}
public Properties getSettings() {
Properties allSettings = new Properties();
allSettings.putAll(sysTestSettings);
allSettings.putAll(samplerSettings);
allSettings.putAll(jmsClientSettings);
return allSettings;
}
public void setSettings(Properties settings) {
for (Iterator i=settings.keySet().iterator(); i.hasNext();) {
String key = (String)i.next();
String val = settings.getProperty(key);
setProperty(key, val);
}
ReflectionUtil.configureClass(this, sysTestSettings);
}
public void setProperty(String key, String value) {
if (key.startsWith(PREFIX_CONFIG_SYSTEM_TEST)) {
sysTestSettings.setProperty(key, value);
} else if (key.startsWith(PerfMeasurementTool.PREFIX_CONFIG_SYSTEM_TEST)) {
samplerSettings.setProperty(key, value);
} else {
jmsClientSettings.setProperty(key, value);
}
}
public String getReportDirectory(){
return reportDirectory;
}
public void setReportDirectory(String reportDirectory){
this.reportDirectory = reportDirectory;
}
public Properties getSysTestSettings() {
return sysTestSettings;
}
public void setSysTestSettings(Properties sysTestSettings) {
this.sysTestSettings = sysTestSettings;
ReflectionUtil.configureClass(this, sysTestSettings);
}
public Properties getSamplerSettings() {
return samplerSettings;
}
public void setSamplerSettings(Properties samplerSettings) {
this.samplerSettings = samplerSettings;
}
public Properties getJmsClientSettings() {
return jmsClientSettings;
}
public void setJmsClientSettings(Properties jmsClientSettings) {
this.jmsClientSettings = jmsClientSettings;
}
public int getNumClients() {
return numClients;
}
public void setNumClients(int numClients) {
this.numClients = numClients;
}
public String getDestDistro() {
return destDistro;
}
public void setDestDistro(String destDistro) {
this.destDistro = destDistro;
}
public int getTotalDests() {
return totalDests;
}
public void setTotalDests(int totalDests) {
this.totalDests = totalDests;
}
public String getReportName() {
if (reportName == null) {
return "clientPerformanceReport.xml";
} else {
return reportName;
}
}
public void setReportName(String reportName) {
this.reportName = reportName;
}
public String getReportType() {
return reportType;
}
public void setReportType(String reportType) {
this.reportType = reportType;
}
public String getClientName() {
if (clientName == null) {
return "JMS Client: ";
} else {
return clientName;
}
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
protected PerformanceReportWriter createPerfWriter() {
if (reportType.equalsIgnoreCase(REPORT_XML_FILE)) {
return new XmlFilePerfReportWriter(getReportDirectory(), getReportName());
} else if (reportType.equalsIgnoreCase(REPORT_VERBOSE)) {
return new VerbosePerfReportWriter();
} else {
// Use verbose if unknown report type
return new VerbosePerfReportWriter();
}
}
protected void distributeDestinations(String distroType, int clientIndex, int numClients, int numDests, Properties clientSettings) {
if (distroType.equalsIgnoreCase(DEST_DISTRO_ALL)) {
clientSettings.setProperty(getDestCountKey(), String.valueOf(numDests));
clientSettings.setProperty(getDestIndexKey(), "0");
} else if (distroType.equalsIgnoreCase(DEST_DISTRO_EQUAL)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
clientSettings.setProperty(getDestCountKey(), String.valueOf(destPerClient));
clientSettings.setProperty(getDestIndexKey(), String.valueOf(destPerClient * clientIndex));
// If there are more clients than destinations, share destinations per client
} else {
clientSettings.setProperty(getDestCountKey(), "1"); // At most one destination per client
clientSettings.setProperty(getDestIndexKey(), String.valueOf(clientIndex % numDests));
}
} else if (distroType.equalsIgnoreCase(DEST_DISTRO_DIVIDE)) {
int destPerClient = (numDests / numClients);
// There are equal or more destinations per client
if (destPerClient > 0) {
int remain = numDests % numClients;
int nextIndex;
if (clientIndex < remain) {
destPerClient++;
nextIndex = clientIndex * destPerClient;
} else {
nextIndex = (clientIndex * destPerClient) + remain;
}
clientSettings.setProperty(getDestCountKey(), String.valueOf(destPerClient));
clientSettings.setProperty(getDestIndexKey(), String.valueOf(nextIndex));
// If there are more clients than destinations, share destinations per client
} else {
clientSettings.setProperty(getDestCountKey(), "1"); // At most one destination per client
clientSettings.setProperty(getDestIndexKey(), String.valueOf(clientIndex % numDests));
}
// Send to all for unknown behavior
} else {
clientSettings.setProperty(getDestCountKey(), String.valueOf(numDests));
clientSettings.setProperty(getDestIndexKey(), "0");
}
}
protected abstract void runJmsClient(String clientName, Properties clientSettings);
protected String getThreadName() {
return "JMS Client Thread: ";
}
protected String getThreadGroupName() {
return "JMS Clients Thread Group";
}
protected String getDestCountKey() {
return "client.destCount";
}
protected String getDestIndexKey() {
return "client.destIndex";
}
}

View File

@ -14,89 +14,109 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.apache.activemq.tool.properties.JmsConsumerProperties;
import org.apache.activemq.tool.properties.JmsClientProperties;
import java.util.Properties; import javax.jms.MessageConsumer;
import javax.jms.JMSException;
import javax.jms.ConnectionFactory;
import javax.jms.Connection; import javax.jms.Connection;
import javax.jms.Destination; import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message; import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener; import javax.jms.MessageListener;
import javax.jms.Topic; import javax.jms.Topic;
public class JmsConsumerClient extends JmsPerformanceSupport { import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicInteger;
public class JmsConsumerClient extends AbstractJmsMeasurableClient {
private static final Log log = LogFactory.getLog(JmsConsumerClient.class); private static final Log log = LogFactory.getLog(JmsConsumerClient.class);
private static final String PREFIX_CONFIG_CONSUMER = "consumer.";
public static final String TIME_BASED_RECEIVING = "time";
public static final String COUNT_BASED_RECEIVING = "count";
protected Properties jmsConsumerSettings = new Properties();
protected MessageConsumer jmsConsumer; protected MessageConsumer jmsConsumer;
protected JmsConsumerProperties client;
protected boolean durable = false; public JmsConsumerClient(ConnectionFactory factory) {
protected boolean asyncRecv = true; this(new JmsConsumerProperties(), factory);
}
protected long recvCount = 1000000; // Receive a million messages by default public JmsConsumerClient(JmsConsumerProperties clientProps, ConnectionFactory factory) {
protected long recvDuration = 5 * 60 * 1000; // Receive for 5 mins by default super(factory);
protected String recvType = TIME_BASED_RECEIVING; client = clientProps;
}
public void receiveMessages() throws JMSException { public void receiveMessages() throws JMSException {
if (listener != null) { if (client.isAsyncRecv()) {
listener.onConfigEnd(this); if (client.getRecvType().equalsIgnoreCase(JmsConsumerProperties.TIME_BASED_RECEIVING)) {
} receiveAsyncTimeBasedMessages(client.getRecvDuration());
if (isAsyncRecv()) {
receiveAsyncMessages();
} else { } else {
receiveSyncMessages(); receiveAsyncCountBasedMessages(client.getRecvCount());
}
} else {
if (client.getRecvType().equalsIgnoreCase(JmsConsumerProperties.TIME_BASED_RECEIVING)) {
receiveSyncTimeBasedMessages(client.getRecvDuration());
} else {
receiveSyncCountBasedMessages(client.getRecvCount());
}
} }
} }
public void receiveSyncMessages() throws JMSException { public void receiveMessages(int destCount) throws JMSException {
this.destCount = destCount;
receiveMessages();
}
public void receiveMessages(int destIndex, int destCount) throws JMSException {
this.destIndex = destIndex;
receiveMessages(destCount);
}
public void receiveSyncTimeBasedMessages(long duration) throws JMSException {
if (getJmsConsumer() == null) { if (getJmsConsumer() == null) {
createJmsConsumer(); createJmsConsumer();
} }
try { try {
getConnection().start(); getConnection().start();
if (listener != null) {
listener.onConsumeStart(this); log.info("Starting to synchronously receive messages for " + duration + " ms...");
} long endTime = System.currentTimeMillis() + duration;
if (getRecvType().equalsIgnoreCase(TIME_BASED_RECEIVING)) {
long endTime = System.currentTimeMillis() + getRecvDuration();
while (System.currentTimeMillis() < endTime) { while (System.currentTimeMillis() < endTime) {
getJmsConsumer().receive(); getJmsConsumer().receive();
incThroughput(); incThroughput();
} }
} else {
int count = 0;
while (count < getRecvCount()) {
getJmsConsumer().receive();
incThroughput();
count++;
}
}
} finally { } finally {
if (listener != null) {
listener.onConsumeEnd(this);
}
getConnection().close(); getConnection().close();
} }
} }
public void receiveAsyncMessages() throws JMSException { public void receiveSyncCountBasedMessages(long count) throws JMSException {
if (getJmsConsumer() == null) {
createJmsConsumer();
}
try {
getConnection().start();
log.info("Starting to synchronously receive " + count + " messages...");
int recvCount = 0;
while (recvCount < count) {
getJmsConsumer().receive();
incThroughput();
recvCount++;
}
} finally {
getConnection().close();
}
}
public void receiveAsyncTimeBasedMessages(long duration) throws JMSException {
if (getJmsConsumer() == null) { if (getJmsConsumer() == null) {
createJmsConsumer(); createJmsConsumer();
} }
if (getRecvType().equalsIgnoreCase(TIME_BASED_RECEIVING)) {
getJmsConsumer().setMessageListener(new MessageListener() { getJmsConsumer().setMessageListener(new MessageListener() {
public void onMessage(Message msg) { public void onMessage(Message msg) {
incThroughput(); incThroughput();
@ -105,85 +125,84 @@ public class JmsConsumerClient extends JmsPerformanceSupport {
try { try {
getConnection().start(); getConnection().start();
if (listener != null) { log.info("Starting to asynchronously receive messages for " + duration + " ms...");
listener.onConsumeStart(this);
}
try { try {
Thread.sleep(getRecvDuration()); Thread.sleep(duration);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new JMSException("JMS consumer thread sleep has been interrupted. Message: " + e.getMessage()); throw new JMSException("JMS consumer thread sleep has been interrupted. Message: " + e.getMessage());
} }
} finally { } finally {
if (listener != null) {
listener.onConsumeEnd(this);
}
getConnection().close(); getConnection().close();
} }
} else { }
final AtomicInteger count = new AtomicInteger(0);
public void receiveAsyncCountBasedMessages(long count) throws JMSException {
if (getJmsConsumer() == null) {
createJmsConsumer();
}
final AtomicInteger recvCount = new AtomicInteger(0);
getJmsConsumer().setMessageListener(new MessageListener() { getJmsConsumer().setMessageListener(new MessageListener() {
public void onMessage(Message msg) { public void onMessage(Message msg) {
incThroughput(); incThroughput();
count.incrementAndGet(); recvCount.incrementAndGet();
count.notify(); recvCount.notify();
} }
}); });
try { try {
getConnection().start(); getConnection().start();
if (listener != null) { log.info("Starting to asynchronously receive " + client.getRecvCount() + " messages...");
listener.onConsumeStart(this);
}
try { try {
while (count.get() < getRecvCount()) { while (recvCount.get() < count) {
count.wait(); recvCount.wait();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new JMSException("JMS consumer thread wait has been interrupted. Message: " + e.getMessage()); throw new JMSException("JMS consumer thread wait has been interrupted. Message: " + e.getMessage());
} }
} finally { } finally {
if (listener != null) {
listener.onConsumeEnd(this);
}
getConnection().close(); getConnection().close();
} }
} }
}
public Connection getConnection() throws JMSException { public Connection getConnection() throws JMSException {
Connection c = super.getConnection(); Connection c = super.getConnection();
if (c.getClientID() == null && isDurable()) { if (c.getClientID() == null && client.isDurable()) {
c.setClientID(getClientName()); c.setClientID(getClientName());
} }
return c; return c;
} }
public MessageConsumer createJmsConsumer() throws JMSException { public MessageConsumer createJmsConsumer() throws JMSException {
Destination[] dest = createDestination(); Destination[] dest = createDestination(destIndex, destCount);
return createJmsConsumer(dest[0]); return createJmsConsumer(dest[0]);
} }
public MessageConsumer createJmsConsumer(Destination dest) throws JMSException { public MessageConsumer createJmsConsumer(Destination dest) throws JMSException {
if (isDurable()) { if (client.isDurable()) {
String clientName = getClientName(); String clientName = getClientName();
if (clientName == null) { if (clientName == null) {
clientName = "JmsConsumer"; clientName = "JmsConsumer";
} }
log.info("Creating durable subscriber to: " + dest.toString());
jmsConsumer = getSession().createDurableSubscriber((Topic) dest, clientName); jmsConsumer = getSession().createDurableSubscriber((Topic) dest, clientName);
} else { } else {
log.info("Creating non-durable consumer to: " + dest.toString());
jmsConsumer = getSession().createConsumer(dest); jmsConsumer = getSession().createConsumer(dest);
} }
return jmsConsumer; return jmsConsumer;
} }
public MessageConsumer createJmsConsumer(Destination dest, String selector, boolean noLocal) throws JMSException { public MessageConsumer createJmsConsumer(Destination dest, String selector, boolean noLocal) throws JMSException {
if (isDurable()) { if (client.isDurable()) {
String clientName = getClientName(); String clientName = getClientName();
if (clientName == null) { if (clientName == null) {
clientName = "JmsConsumer"; clientName = "JmsConsumer";
} }
log.info("Creating durable subscriber to: " + dest.toString());
jmsConsumer = getSession().createDurableSubscriber((Topic) dest, clientName, selector, noLocal); jmsConsumer = getSession().createDurableSubscriber((Topic) dest, clientName, selector, noLocal);
} else { } else {
log.info("Creating non-durable consumer to: " + dest.toString());
jmsConsumer = getSession().createConsumer(dest, selector, noLocal); jmsConsumer = getSession().createConsumer(dest, selector, noLocal);
} }
return jmsConsumer; return jmsConsumer;
@ -193,101 +212,11 @@ public class JmsConsumerClient extends JmsPerformanceSupport {
return jmsConsumer; return jmsConsumer;
} }
public Properties getJmsConsumerSettings() { public JmsClientProperties getClient() {
return jmsConsumerSettings; return client;
} }
public void setJmsConsumerSettings(Properties jmsConsumerSettings) { public void setClient(JmsClientProperties clientProps) {
this.jmsConsumerSettings = jmsConsumerSettings; client = (JmsConsumerProperties)clientProps;
ReflectionUtil.configureClass(this, jmsConsumerSettings);
}
public boolean isDurable() {
return durable;
}
public void setDurable(boolean durable) {
this.durable = durable;
}
public boolean isAsyncRecv() {
return asyncRecv;
}
public void setAsyncRecv(boolean asyncRecv) {
this.asyncRecv = asyncRecv;
}
public long getRecvCount() {
return recvCount;
}
public void setRecvCount(long recvCount) {
this.recvCount = recvCount;
}
public long getRecvDuration() {
return recvDuration;
}
public void setRecvDuration(long recvDuration) {
this.recvDuration = recvDuration;
}
public String getRecvType() {
return recvType;
}
public void setRecvType(String recvType) {
this.recvType = recvType;
}
public Properties getSettings() {
Properties allSettings = new Properties(jmsConsumerSettings);
allSettings.putAll(super.getSettings());
return allSettings;
}
public void setSettings(Properties settings) {
super.setSettings(settings);
ReflectionUtil.configureClass(this, jmsConsumerSettings);
}
public void setProperty(String key, String value) {
if (key.startsWith(PREFIX_CONFIG_CONSUMER)) {
jmsConsumerSettings.setProperty(key, value);
} else {
super.setProperty(key, value);
}
}
public static void main(String[] args) throws JMSException {
Properties samplerSettings = new Properties();
Properties consumerSettings = new Properties();
for (int i = 0; i < args.length; i++) {
// Get property define options only
int index = args[i].indexOf("=");
String key = args[i].substring(0, index);
String val = args[i].substring(index + 1);
if (key.startsWith("sampler.")) {
samplerSettings.setProperty(key, val);
} else {
consumerSettings.setProperty(key, val);
}
}
JmsConsumerClient client = new JmsConsumerClient();
client.setSettings(consumerSettings);
PerfMeasurementTool sampler = new PerfMeasurementTool();
sampler.setSamplerSettings(samplerSettings);
sampler.registerClient(client);
sampler.startSampler();
client.setPerfEventListener(sampler);
client.receiveMessages();
} }
} }

View File

@ -16,74 +16,72 @@
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool;
import org.apache.activemq.tool.properties.JmsClientSystemProperties;
import org.apache.activemq.tool.properties.JmsConsumerSystemProperties;
import org.apache.activemq.tool.properties.JmsConsumerProperties;
import org.apache.activemq.tool.properties.JmsClientProperties;
import org.apache.activemq.tool.sampler.ThroughputSamplerTask;
import javax.jms.JMSException; import javax.jms.JMSException;
import java.util.Properties; import java.util.Properties;
public class JmsConsumerSystem extends JmsClientSystemSupport { public class JmsConsumerSystem extends AbstractJmsClientSystem {
protected JmsConsumerSystemProperties sysTest = new JmsConsumerSystemProperties();
protected JmsConsumerProperties consumer = new JmsConsumerProperties();
public String getReportName() { public JmsClientSystemProperties getSysTest() {
if (reportName == null) { return sysTest;
return "JmsConsumer_Client" + getNumClients() + "_Dest" + getTotalDests() + "_" + getDestDistro() + ".xml";
} else {
return reportName;
}
} }
public String getClientName() { public void setSysTest(JmsClientSystemProperties sysTestProps) {
if (clientName == null) { sysTest = (JmsConsumerSystemProperties)sysTestProps;
return "JmsConsumer";
} else {
return clientName;
}
} }
protected void runJmsClient(String clientName, Properties clientSettings) { public JmsClientProperties getJmsClientProperties() {
PerfMeasurementTool sampler = getPerformanceSampler(); return getConsumer();
}
JmsConsumerClient consumer = new JmsConsumerClient(); public JmsConsumerProperties getConsumer() {
consumer.setSettings(clientSettings); return consumer;
consumer.setClientName(clientName); }
public void setConsumer(JmsConsumerProperties consumer) {
this.consumer = consumer;
}
protected void runJmsClient(String clientName, int clientDestIndex, int clientDestCount) {
ThroughputSamplerTask sampler = getTpSampler();
JmsConsumerClient consumerClient = new JmsConsumerClient(consumer, jmsConnFactory);
consumerClient.setClientName(clientName);
if (sampler != null) { if (sampler != null) {
sampler.registerClient(consumer); sampler.registerClient(consumerClient);
consumer.setPerfEventListener(sampler);
} }
try { try {
consumer.receiveMessages(); consumerClient.receiveMessages(clientDestIndex, clientDestCount);
} catch (JMSException e) { } catch (JMSException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
protected String getThreadName() { public static void main(String[] args) {
return "JMS Consumer Thread: "; Properties props = new Properties();
} for (int i=0; i<args.length; i++) {
protected String getThreadGroupName() {
return "JMS Consumer Thread Group";
}
protected String getDestCountKey() {
return "consumer.destCount";
}
protected String getDestIndexKey() {
return "consumer.destIndex";
}
public static void main(String[] args) throws JMSException {
Properties sysSettings = new Properties();
for (int i = 0; i < args.length; i++) {
// Get property define options only
int index = args[i].indexOf("="); int index = args[i].indexOf("=");
String key = args[i].substring(0, index); String key = args[i].substring(0, index);
String val = args[i].substring(index + 1); String val = args[i].substring(index + 1);
sysSettings.setProperty(key, val); props.setProperty(key, val);
} }
JmsConsumerSystem sysTest = new JmsConsumerSystem(); JmsConsumerSystem sys = new JmsConsumerSystem();
sysTest.setSettings(sysSettings); sys.configureProperties(props);
sysTest.runSystemTest();
try {
sys.runSystemTest();
} catch (JMSException e) {
e.printStackTrace();
}
} }
} }

View File

@ -1,102 +0,0 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.activemq.tool.spi.SPIConnectionFactory;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import java.util.Properties;
import java.util.Iterator;
public class JmsFactorySupport {
private static final Log log = LogFactory.getLog(JmsFactorySupport.class);
private static final String PREFIX_CONFIG_FACTORY = "factory.";
private SPIConnectionFactory spiFactory;
protected ConnectionFactory jmsFactory;
protected Properties jmsFactorySettings = new Properties();
public ConnectionFactory createConnectionFactory(String spiClass) throws JMSException {
jmsFactory = loadJmsFactory(spiClass, jmsFactorySettings);
return jmsFactory;
}
protected ConnectionFactory loadJmsFactory(String spiClass, Properties factorySettings) throws JMSException {
try {
Class spi = Class.forName(spiClass);
spiFactory = (SPIConnectionFactory)spi.newInstance();
ConnectionFactory jmsFactory = spiFactory.createConnectionFactory(factorySettings);
log.debug("Created: " + jmsFactory.getClass().getName() + " using SPIConnectionFactory: " + spiFactory.getClass().getName());
return jmsFactory;
} catch (Exception e) {
e.printStackTrace();
throw new JMSException(e.getMessage());
}
}
public ConnectionFactory getJmsFactory() {
return jmsFactory;
}
public Properties getJmsFactorySettings() {
return jmsFactorySettings;
}
public void setJmsFactorySettings(Properties jmsFactorySettings) {
this.jmsFactorySettings = jmsFactorySettings;
if (spiFactory != null) {
try {
spiFactory.configureConnectionFactory(jmsFactory, jmsFactorySettings);
} catch (Exception e) {
log.warn(e);
}
}
}
public Properties getSettings() {
return jmsFactorySettings;
}
public void setSettings(Properties settings) {
for (Iterator i=settings.keySet().iterator(); i.hasNext();) {
String key = (String)i.next();
String val = settings.getProperty(key);
setProperty(key, val);
}
if (spiFactory != null) {
try {
spiFactory.configureConnectionFactory(jmsFactory, jmsFactorySettings);
} catch (Exception e) {
e.printStackTrace();
log.warn(e);
}
}
}
public void setProperty(String key, String value) {
if (key.startsWith(PREFIX_CONFIG_FACTORY)) {
jmsFactorySettings.setProperty(key, value);
} else {
log.warn("Unknown setting: " + key + "=" + value);
}
}
}

View File

@ -16,51 +16,60 @@
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool;
import org.apache.activemq.tool.properties.JmsProducerProperties;
import org.apache.activemq.tool.properties.JmsClientProperties;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import javax.jms.*; import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
import javax.jms.TextMessage;
import javax.jms.JMSException;
import javax.jms.Destination;
import javax.jms.DeliveryMode;
import java.util.Arrays; import java.util.Arrays;
import java.util.Properties;
public class JmsProducerClient extends JmsPerformanceSupport { public class JmsProducerClient extends AbstractJmsMeasurableClient {
private static final Log log = LogFactory.getLog(JmsProducerClient.class); private static final Log log = LogFactory.getLog(JmsProducerClient.class);
private static final String PREFIX_CONFIG_PRODUCER = "producer."; protected JmsProducerProperties client;
public static final String TIME_BASED_SENDING = "time";
public static final String COUNT_BASED_SENDING = "count";
public static final String DELIVERY_MODE_PERSISTENT = "persistent";
public static final String DELIVERY_MODE_NON_PERSISTENT = "nonpersistent";
protected Properties jmsProducerSettings = new Properties();
protected MessageProducer jmsProducer; protected MessageProducer jmsProducer;
protected TextMessage jmsTextMessage; protected TextMessage jmsTextMessage;
protected String deliveryMode = DELIVERY_MODE_NON_PERSISTENT; public JmsProducerClient(ConnectionFactory factory) {
protected int messageSize = 1024; // Send 1kb messages by default this(new JmsProducerProperties(), factory);
protected long sendCount = 1000000; // Send a million messages by default }
protected long sendDuration = 5 * 60 * 1000; // Send for 5 mins by default
protected String sendType = TIME_BASED_SENDING; public JmsProducerClient(JmsProducerProperties clientProps, ConnectionFactory factory) {
super(factory);
this.client = clientProps;
}
public void sendMessages() throws JMSException { public void sendMessages() throws JMSException {
if (listener != null) {
listener.onConfigEnd(this);
}
// Send a specific number of messages // Send a specific number of messages
if (sendType.equalsIgnoreCase(COUNT_BASED_SENDING)) { if (client.getSendType().equalsIgnoreCase(JmsProducerProperties.COUNT_BASED_SENDING)) {
sendCountBasedMessages(getSendCount()); sendCountBasedMessages(client.getSendCount());
// Send messages for a specific duration // Send messages for a specific duration
} else { } else {
sendTimeBasedMessages(getSendDuration()); sendTimeBasedMessages(client.getSendDuration());
} }
} }
public void sendMessages(int destCount) throws JMSException {
this.destCount = destCount;
sendMessages();
}
public void sendMessages(int destIndex, int destCount) throws JMSException {
this.destIndex = destIndex;
sendMessages(destCount);
}
public void sendCountBasedMessages(long messageCount) throws JMSException { public void sendCountBasedMessages(long messageCount) throws JMSException {
// Parse through different ways to send messages // Parse through different ways to send messages
// Avoided putting the condition inside the loop to prevent effect on performance // Avoided putting the condition inside the loop to prevent effect on performance
Destination[] dest = createDestination(); Destination[] dest = createDestination(destIndex, destCount);
// Create a producer, if none is created. // Create a producer, if none is created.
if (getJmsProducer() == null) { if (getJmsProducer() == null) {
@ -72,11 +81,13 @@ public class JmsProducerClient extends JmsPerformanceSupport {
} }
try { try {
getConnection().start(); getConnection().start();
if (listener != null) { log.info("Starting to publish " + client.getMessageSize() + " byte(s) of " + messageCount + " messages...");
listener.onPublishStart(this);
}
// Send one type of message only, avoiding the creation of different messages on sending // Send one type of message only, avoiding the creation of different messages on sending
if (getJmsTextMessage() != null) { if (!client.isCreateNewMsg()) {
// Create only a single message
createJmsTextMessage();
// Send to more than one actual destination // Send to more than one actual destination
if (dest.length > 1) { if (dest.length > 1) {
for (int i = 0; i < messageCount; i++) { for (int i = 0; i < messageCount; i++) {
@ -115,9 +126,6 @@ public class JmsProducerClient extends JmsPerformanceSupport {
} }
} }
} finally { } finally {
if (listener != null) {
listener.onPublishEnd(this);
}
getConnection().close(); getConnection().close();
} }
} }
@ -127,7 +135,7 @@ public class JmsProducerClient extends JmsPerformanceSupport {
// Parse through different ways to send messages // Parse through different ways to send messages
// Avoided putting the condition inside the loop to prevent effect on performance // Avoided putting the condition inside the loop to prevent effect on performance
Destination[] dest = createDestination(); Destination[] dest = createDestination(destIndex, destCount);
// Create a producer, if none is created. // Create a producer, if none is created.
if (getJmsProducer() == null) { if (getJmsProducer() == null) {
@ -140,12 +148,13 @@ public class JmsProducerClient extends JmsPerformanceSupport {
try { try {
getConnection().start(); getConnection().start();
if (listener != null) { log.info("Starting to publish " + client.getMessageSize() + " byte(s) messages for " + duration + " ms");
listener.onPublishStart(this);
}
// Send one type of message only, avoiding the creation of different messages on sending // Send one type of message only, avoiding the creation of different messages on sending
if (getJmsTextMessage() != null) { if (!client.isCreateNewMsg()) {
// Create only a single message
createJmsTextMessage();
// Send to more than one actual destination // Send to more than one actual destination
if (dest.length > 1) { if (dest.length > 1) {
while (System.currentTimeMillis() < endTime) { while (System.currentTimeMillis() < endTime) {
@ -186,27 +195,17 @@ public class JmsProducerClient extends JmsPerformanceSupport {
} }
} }
} finally { } finally {
if (listener != null) {
listener.onPublishEnd(this);
}
getConnection().close(); getConnection().close();
} }
} }
public Properties getJmsProducerSettings() {
return jmsProducerSettings;
}
public void setJmsProducerSettings(Properties jmsProducerSettings) {
this.jmsProducerSettings = jmsProducerSettings;
ReflectionUtil.configureClass(this, jmsProducerSettings);
}
public MessageProducer createJmsProducer() throws JMSException { public MessageProducer createJmsProducer() throws JMSException {
jmsProducer = getSession().createProducer(null); jmsProducer = getSession().createProducer(null);
if (getDeliveryMode().equalsIgnoreCase(DELIVERY_MODE_PERSISTENT)) { if (client.getDeliveryMode().equalsIgnoreCase(JmsProducerProperties.DELIVERY_MODE_PERSISTENT)) {
log.info("Creating producer to possible multiple destinations with persistent delivery.");
jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT); jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
} else if (getDeliveryMode().equalsIgnoreCase(DELIVERY_MODE_NON_PERSISTENT)) { } else if (client.getDeliveryMode().equalsIgnoreCase(JmsProducerProperties.DELIVERY_MODE_NON_PERSISTENT)) {
log.info("Creating producer to possible multiple destinations with non-persistent delivery.");
jmsProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); jmsProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
} else { } else {
log.warn("Unknown deliveryMode value. Defaulting to non-persistent."); log.warn("Unknown deliveryMode value. Defaulting to non-persistent.");
@ -217,9 +216,11 @@ public class JmsProducerClient extends JmsPerformanceSupport {
public MessageProducer createJmsProducer(Destination dest) throws JMSException { public MessageProducer createJmsProducer(Destination dest) throws JMSException {
jmsProducer = getSession().createProducer(dest); jmsProducer = getSession().createProducer(dest);
if (getDeliveryMode().equalsIgnoreCase(DELIVERY_MODE_PERSISTENT)) { if (client.getDeliveryMode().equalsIgnoreCase(JmsProducerProperties.DELIVERY_MODE_PERSISTENT)) {
log.info("Creating producer to: " + dest.toString() + " with persistent delivery.");
jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT); jmsProducer.setDeliveryMode(DeliveryMode.PERSISTENT);
} else if (getDeliveryMode().equalsIgnoreCase(DELIVERY_MODE_NON_PERSISTENT)) { } else if (client.getDeliveryMode().equalsIgnoreCase(JmsProducerProperties.DELIVERY_MODE_NON_PERSISTENT)) {
log.info("Creating producer to: " + dest.toString() + " with non-persistent delivery.");
jmsProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); jmsProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
} else { } else {
log.warn("Unknown deliveryMode value. Defaulting to non-persistent."); log.warn("Unknown deliveryMode value. Defaulting to non-persistent.");
@ -233,7 +234,7 @@ public class JmsProducerClient extends JmsPerformanceSupport {
} }
public TextMessage createJmsTextMessage() throws JMSException { public TextMessage createJmsTextMessage() throws JMSException {
return createJmsTextMessage(getMessageSize()); return createJmsTextMessage(client.getMessageSize());
} }
public TextMessage createJmsTextMessage(int size) throws JMSException { public TextMessage createJmsTextMessage(int size) throws JMSException {
@ -242,7 +243,7 @@ public class JmsProducerClient extends JmsPerformanceSupport {
} }
public TextMessage createJmsTextMessage(String text) throws JMSException { public TextMessage createJmsTextMessage(String text) throws JMSException {
jmsTextMessage = getSession().createTextMessage(buildText(text, getMessageSize())); jmsTextMessage = getSession().createTextMessage(buildText(text, client.getMessageSize()));
return jmsTextMessage; return jmsTextMessage;
} }
@ -250,100 +251,17 @@ public class JmsProducerClient extends JmsPerformanceSupport {
return jmsTextMessage; return jmsTextMessage;
} }
public JmsClientProperties getClient() {
return client;
}
public void setClient(JmsClientProperties clientProps) {
client = (JmsProducerProperties)clientProps;
}
protected String buildText(String text, int size) { protected String buildText(String text, int size) {
byte[] data = new byte[size - text.length()]; byte[] data = new byte[size - text.length()];
Arrays.fill(data, (byte) 0); Arrays.fill(data, (byte) 0);
return text + new String(data); return text + new String(data);
} }
public String getDeliveryMode() {
return deliveryMode;
}
public void setDeliveryMode(String deliveryMode) {
this.deliveryMode = deliveryMode;
}
public int getMessageSize() {
return messageSize;
}
public void setMessageSize(int messageSize) {
this.messageSize = messageSize;
}
public long getSendCount() {
return sendCount;
}
public void setSendCount(long sendCount) {
this.sendCount = sendCount;
}
public long getSendDuration() {
return sendDuration;
}
public void setSendDuration(long sendDuration) {
this.sendDuration = sendDuration;
}
public String getSendType() {
return sendType;
}
public void setSendType(String sendType) {
this.sendType = sendType;
}
public Properties getSettings() {
Properties allSettings = new Properties(jmsProducerSettings);
allSettings.putAll(super.getSettings());
return allSettings;
}
public void setSettings(Properties settings) {
super.setSettings(settings);
ReflectionUtil.configureClass(this, jmsProducerSettings);
}
public void setProperty(String key, String value) {
if (key.startsWith(PREFIX_CONFIG_PRODUCER)) {
jmsProducerSettings.setProperty(key, value);
} else {
super.setProperty(key, value);
}
}
public static void main(String[] args) throws JMSException {
Properties samplerSettings = new Properties();
Properties producerSettings = new Properties();
for (int i = 0; i < args.length; i++) {
// Get property define options only
int index = args[i].indexOf("=");
String key = args[i].substring(0, index);
String val = args[i].substring(index + 1);
if (key.startsWith("sampler.")) {
samplerSettings.setProperty(key, val);
} else {
producerSettings.setProperty(key, val);
}
}
JmsProducerClient client = new JmsProducerClient();
client.setSettings(producerSettings);
PerfMeasurementTool sampler = new PerfMeasurementTool();
sampler.setSamplerSettings(samplerSettings);
sampler.registerClient(client);
sampler.startSampler();
client.setPerfEventListener(sampler);
// This will reuse only a single message every send, which will improve performance
client.createJmsTextMessage();
client.sendMessages();
}
} }

View File

@ -16,76 +16,72 @@
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool;
import org.apache.activemq.tool.properties.JmsClientSystemProperties;
import org.apache.activemq.tool.properties.JmsProducerSystemProperties;
import org.apache.activemq.tool.properties.JmsProducerProperties;
import org.apache.activemq.tool.properties.JmsClientProperties;
import org.apache.activemq.tool.sampler.ThroughputSamplerTask;
import javax.jms.JMSException; import javax.jms.JMSException;
import java.util.Properties; import java.util.Properties;
public class JmsProducerSystem extends JmsClientSystemSupport { public class JmsProducerSystem extends AbstractJmsClientSystem {
protected JmsProducerSystemProperties sysTest = new JmsProducerSystemProperties();
protected JmsProducerProperties producer = new JmsProducerProperties();
public String getReportName() { public JmsClientSystemProperties getSysTest() {
if (reportName == null) { return sysTest;
return "JmsProducer_Client" + getNumClients() + "_Dest" + getTotalDests() + "_" + getDestDistro() + ".xml";
} else {
return reportName;
}
} }
public String getClientName() { public void setSysTest(JmsClientSystemProperties sysTestProps) {
if (clientName == null) { sysTest = (JmsProducerSystemProperties)sysTestProps;
return "JmsProducer";
} else {
return clientName;
}
} }
protected void runJmsClient(String clientName, Properties clientSettings) { public JmsClientProperties getJmsClientProperties() {
PerfMeasurementTool sampler = getPerformanceSampler(); return getProducer();
}
JmsProducerClient producer = new JmsProducerClient(); public JmsProducerProperties getProducer() {
producer.setSettings(clientSettings); return producer;
producer.setClientName(clientName); }
public void setProducer(JmsProducerProperties producer) {
this.producer = producer;
}
protected void runJmsClient(String clientName, int clientDestIndex, int clientDestCount) {
ThroughputSamplerTask sampler = getTpSampler();
JmsProducerClient producerClient = new JmsProducerClient(producer, jmsConnFactory);
producerClient.setClientName(clientName);
if (sampler != null) { if (sampler != null) {
sampler.registerClient(producer); sampler.registerClient(producerClient);
producer.setPerfEventListener(sampler);
} }
try { try {
producer.createJmsTextMessage(); producerClient.sendMessages(clientDestIndex, clientDestCount);
producer.sendMessages();
} catch (JMSException e) { } catch (JMSException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
protected String getThreadName() {
return "JMS Producer Thread: ";
}
protected String getThreadGroupName() {
return "JMS Producer Thread Group";
}
protected String getDestCountKey() {
return "producer.destCount";
}
protected String getDestIndexKey() {
return "producer.destIndex";
}
public static void main(String[] args) { public static void main(String[] args) {
Properties sysSettings = new Properties(); Properties props = new Properties();
for (int i=0; i<args.length; i++) {
for (int i = 0; i < args.length; i++) {
// Get property define options only
int index = args[i].indexOf("="); int index = args[i].indexOf("=");
String key = args[i].substring(0, index); String key = args[i].substring(0, index);
String val = args[i].substring(index + 1); String val = args[i].substring(index + 1);
sysSettings.setProperty(key, val); props.setProperty(key, val);
} }
JmsProducerSystem sysTest = new JmsProducerSystem(); JmsProducerSystem sys = new JmsProducerSystem();
sysTest.setSettings(sysSettings); sys.configureProperties(props);
sysTest.runSystemTest();
try {
sys.runSystemTest();
} catch (JMSException e) {
e.printStackTrace();
}
} }
} }

View File

@ -1,45 +0,0 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool;
import javax.jms.JMSException;
public class PerfEventAdapter implements PerfEventListener {
public void onConfigStart(PerfMeasurable client) {
}
public void onConfigEnd(PerfMeasurable client) {
}
public void onPublishStart(PerfMeasurable client) {
}
public void onPublishEnd(PerfMeasurable client) {
}
public void onConsumeStart(PerfMeasurable client) {
}
public void onConsumeEnd(PerfMeasurable client) {
}
public void onJMSException(PerfMeasurable client, JMSException e) {
}
public void onException(PerfMeasurable client, Exception e) {
}
}

View File

@ -1,190 +0,0 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool;
import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
import javax.jms.JMSException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import org.apache.activemq.tool.reports.PerformanceReportWriter;
public class PerfMeasurementTool implements PerfEventListener, Runnable {
public static final String PREFIX_CONFIG_SYSTEM_TEST = "sampler.";
private long duration = 5 * 60 * 1000; // 5 mins by default test duration
private long interval = 1000; // 1 sec sample interval
private long rampUpTime = 1 * 60 * 1000; // 1 min default test ramp up time
private long rampDownTime = 1 * 60 * 1000; // 1 min default test ramp down time
private long sampleIndex = 0;
private AtomicBoolean start = new AtomicBoolean(false);
private AtomicBoolean stop = new AtomicBoolean(false);
private AtomicBoolean isRunning = new AtomicBoolean(false);
private PerformanceReportWriter perfWriter = null;
private Properties samplerSettings = new Properties();
private List perfClients = new ArrayList();
public void registerClient(PerfMeasurable client) {
client.setPerfEventListener(this);
perfClients.add(client);
}
public void registerClient(PerfMeasurable[] clients) {
for (int i = 0; i < clients.length; i++) {
registerClient(clients[i]);
}
}
public Properties getSamplerSettings() {
return samplerSettings;
}
public void setSamplerSettings(Properties samplerSettings) {
this.samplerSettings = samplerSettings;
ReflectionUtil.configureClass(this, samplerSettings);
}
public PerformanceReportWriter getPerfWriter() {
return perfWriter;
}
public void setPerfWriter(PerformanceReportWriter writer) {
this.perfWriter = writer;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getInterval() {
return interval;
}
public void setInterval(long interval) {
this.interval = interval;
}
public long getRampUpTime() {
return rampUpTime;
}
public void setRampUpTime(long rampUpTime) {
this.rampUpTime = rampUpTime;
}
public long getRampDownTime() {
return rampDownTime;
}
public void setRampDownTime(long rampDownTime) {
this.rampDownTime = rampDownTime;
}
public void onConfigStart(PerfMeasurable client) {
}
public void onConfigEnd(PerfMeasurable client) {
}
public void onPublishStart(PerfMeasurable client) {
}
public void onPublishEnd(PerfMeasurable client) {
}
public void onConsumeStart(PerfMeasurable client) {
}
public void onConsumeEnd(PerfMeasurable client) {
}
public void onJMSException(PerfMeasurable client, JMSException e) {
}
public void onException(PerfMeasurable client, Exception e) {
stop.set(true);
}
public void startSampler() {
Thread t = new Thread(this);
t.setName("Performance Sampler");
isRunning.set(true);
t.start();
}
public void run() {
// Compute for the actual duration window of the sampler
long endTime = System.currentTimeMillis() + duration - rampDownTime;
try {
try {
Thread.sleep(rampUpTime);
} catch (InterruptedException e) {
}
// Let's reset the throughput first and start getting the samples
for (Iterator i = perfClients.iterator(); i.hasNext();) {
PerfMeasurable client = (PerfMeasurable) i.next();
client.reset();
}
while (System.currentTimeMillis() < endTime && !stop.get()) {
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
}
sampleClients();
sampleIndex++;
}
} finally {
isRunning.set(false);
synchronized (isRunning) {
isRunning.notifyAll();
}
}
}
public void sampleClients() {
for (Iterator i = perfClients.iterator(); i.hasNext();) {
PerfMeasurable client = (PerfMeasurable) i.next();
if (perfWriter != null) {
perfWriter.writePerfData("index=" + sampleIndex + ",clientName=" + client.getClientName() + ",throughput=" + client.getThroughput());
}
client.reset();
}
}
public void waitForSamplerToFinish(long timeout) {
while (isRunning.get()) {
try {
synchronized (isRunning) {
isRunning.wait(timeout);
}
} catch (InterruptedException e) {
}
}
}
}

View File

@ -14,17 +14,21 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool.properties;
import javax.jms.JMSException; import java.util.Properties;
public interface PerfEventListener { public abstract class AbstractObjectProperties implements ReflectionConfigurable {
public void onConfigStart(PerfMeasurable client);
public void onConfigEnd(PerfMeasurable client); public void configureProperties(Properties props) {
public void onPublishStart(PerfMeasurable client); ReflectionUtil.configureClass(this, props);
public void onPublishEnd(PerfMeasurable client); }
public void onConsumeStart(PerfMeasurable client);
public void onConsumeEnd(PerfMeasurable client); public Properties retrieveProperties(Properties props) {
public void onJMSException(PerfMeasurable client, JMSException e); return null;
public void onException(PerfMeasurable client, Exception e); }
public boolean acceptConfig(String key, String val) {
return true; // accept by default
}
} }

View File

@ -0,0 +1,61 @@
/**
* Copyright 2005-2006 The Apache Software Foundation
* <p/>
* Licensed 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.activemq.tool.properties;
public class JmsClientProperties extends AbstractObjectProperties {
public static final String SESSION_AUTO_ACKNOWLEDGE = "autoAck";
public static final String SESSION_CLIENT_ACKNOWLEDGE = "clientAck";
public static final String SESSION_DUPS_OK_ACKNOWLEDGE = "dupsAck";
public static final String SESSION_TRANSACTED = "transacted";
protected String destName = "TEST.FOO";
protected boolean destComposite = false;
protected String sessAckMode = SESSION_AUTO_ACKNOWLEDGE;
protected boolean sessTransacted = false;
public String getDestName() {
return destName;
}
public void setDestName(String destName) {
this.destName = destName;
}
public boolean isDestComposite() {
return destComposite;
}
public void setDestComposite(boolean destComposite) {
this.destComposite = destComposite;
}
public String getSessAckMode() {
return sessAckMode;
}
public void setSessAckMode(String sessAckMode) {
this.sessAckMode = sessAckMode;
}
public boolean isSessTransacted() {
return sessTransacted;
}
public void setSessTransacted(boolean sessTransacted) {
this.sessTransacted = sessTransacted;
}
}

View File

@ -0,0 +1,113 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.properties;
public class JmsClientSystemProperties extends AbstractObjectProperties {
public static final String DEST_DISTRO_ALL = "all"; // Each client will send/receive to all destination;
public static final String DEST_DISTRO_EQUAL = "equal"; // Equally divide the number of destinations to the number of clients
public static final String DEST_DISTRO_DIVIDE = "divide"; // Divide the destination among the clients, even if some have more destination than others
public static final String REPORT_VERBOSE = "verbose"; // Report would be generated to the console
public static final String REPORT_XML_FILE = "xml"; // Report would be generated to an xml file
public static final String SAMPLER_TP = "tp";
public static final String SAMPLER_CPU = "cpu";
protected String reportType = REPORT_XML_FILE;
protected String reportDir = "./";
protected String reportName = null;
protected String samplers = SAMPLER_TP + "," + SAMPLER_CPU; // Start both samplers
protected String spiClass = "org.apache.activemq.tool.spi.ActiveMQClassLoaderSPI";
protected String clientPrefix = "JmsClient";
protected int numClients = 1;
protected int totalDests = 1;
protected String destDistro = DEST_DISTRO_ALL;
public String getReportType() {
return reportType;
}
public void setReportType(String reportType) {
this.reportType = reportType;
}
public String getReportDir() {
return reportDir;
}
public void setReportDir(String reportDir) {
this.reportDir = reportDir;
}
public String getReportName() {
return reportName;
}
public void setReportName(String reportName) {
this.reportName = reportName;
}
public String getSamplers() {
return samplers;
}
public void setSamplers(String samplers) {
this.samplers = samplers;
}
public String getSpiClass() {
return spiClass;
}
public void setSpiClass(String spiClass) {
this.spiClass = spiClass;
}
public String getClientPrefix() {
return clientPrefix;
}
public void setClientPrefix(String clientPrefix) {
this.clientPrefix = clientPrefix;
}
public int getNumClients() {
return numClients;
}
public void setNumClients(int numClients) {
this.numClients = numClients;
}
public int getTotalDests() {
return totalDests;
}
public void setTotalDests(int totalDests) {
this.totalDests = totalDests;
}
public String getDestDistro() {
return destDistro;
}
public void setDestDistro(String destDistro) {
this.destDistro = destDistro;
}
}

View File

@ -0,0 +1,68 @@
/**
* Copyright 2005-2006 The Apache Software Foundation
* <p/>
* Licensed 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.activemq.tool.properties;
public class JmsConsumerProperties extends JmsClientProperties {
public static final String TIME_BASED_RECEIVING = "time"; // Receive messages on a time-based interval
public static final String COUNT_BASED_RECEIVING = "count"; // Receive a specific count of messages
protected boolean durable = false; // Consumer is a durable subscriber
protected boolean asyncRecv = true; // If true, use onMessage() to receive messages, else use receive()
protected long recvCount = 1000000; // Receive a million messages by default
protected long recvDuration = 5 * 60 * 1000; // Receive for 5 mins by default
protected String recvType = TIME_BASED_RECEIVING;
public boolean isDurable() {
return durable;
}
public void setDurable(boolean durable) {
this.durable = durable;
}
public boolean isAsyncRecv() {
return asyncRecv;
}
public void setAsyncRecv(boolean asyncRecv) {
this.asyncRecv = asyncRecv;
}
public long getRecvCount() {
return recvCount;
}
public void setRecvCount(long recvCount) {
this.recvCount = recvCount;
}
public long getRecvDuration() {
return recvDuration;
}
public void setRecvDuration(long recvDuration) {
this.recvDuration = recvDuration;
}
public String getRecvType() {
return recvType;
}
public void setRecvType(String recvType) {
this.recvType = recvType;
}
}

View File

@ -0,0 +1,23 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.properties;
public class JmsConsumerSystemProperties extends JmsClientSystemProperties {
public JmsConsumerSystemProperties() {
clientPrefix = "JmsConsumer";
}
}

View File

@ -0,0 +1,34 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.properties;
import java.util.Properties;
public class JmsFactoryProperties extends AbstractObjectProperties {
Properties factorySettings = new Properties();
public boolean acceptConfig(String key, String val) {
// Since we do not know the specific properties of each factory,
// lets cache it first and give it to the spi later
factorySettings.setProperty(key, val);
return false;
}
public Properties getFactorySettings() {
return factorySettings;
}
}

View File

@ -0,0 +1,79 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.properties;
public class JmsProducerProperties extends JmsClientProperties {
public static final String TIME_BASED_SENDING = "time"; // Produce messages base on a time interval
public static final String COUNT_BASED_SENDING = "count"; // Produce a specific count of messages
public static final String DELIVERY_MODE_PERSISTENT = "persistent"; // Persistent message delivery
public static final String DELIVERY_MODE_NON_PERSISTENT = "nonpersistent"; // Non-persistent message delivery
protected String deliveryMode = DELIVERY_MODE_NON_PERSISTENT; // Message delivery mode
protected int messageSize = 1024; // Send 1kb messages by default
protected long sendCount = 1000000; // Send a million messages by default
protected long sendDuration = 5 * 60 * 1000; // Send for 5 mins by default
protected String sendType = TIME_BASED_SENDING;
protected boolean createNewMsg = false; // If true, create a different message on each send, otherwise reuse.
public String getDeliveryMode() {
return deliveryMode;
}
public void setDeliveryMode(String deliveryMode) {
this.deliveryMode = deliveryMode;
}
public int getMessageSize() {
return messageSize;
}
public void setMessageSize(int messageSize) {
this.messageSize = messageSize;
}
public long getSendCount() {
return sendCount;
}
public void setSendCount(long sendCount) {
this.sendCount = sendCount;
}
public long getSendDuration() {
return sendDuration;
}
public void setSendDuration(long sendDuration) {
this.sendDuration = sendDuration;
}
public String getSendType() {
return sendType;
}
public void setSendType(String sendType) {
this.sendType = sendType;
}
public boolean isCreateNewMsg() {
return createNewMsg;
}
public void setCreateNewMsg(boolean createNewMsg) {
this.createNewMsg = createNewMsg;
}
}

View File

@ -0,0 +1,23 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.properties;
public class JmsProducerSystemProperties extends JmsClientSystemProperties {
public JmsProducerSystemProperties() {
clientPrefix = "JmsProducer";
}
}

View File

@ -1,28 +1,24 @@
/** /**
*
* Copyright 2005-2006 The Apache Software Foundation * Copyright 2005-2006 The Apache Software Foundation
* * <p/>
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* * <p/>
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* * <p/>
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool.properties;
import java.util.Properties; import java.util.Properties;
public interface PerfMeasurable { public interface ReflectionConfigurable {
public void reset(); public void configureProperties(Properties props);
public String getClientName(); public Properties retrieveProperties(Properties props);
public long getThroughput(); public boolean acceptConfig(String key, String val);
public Properties getSettings();
public void setPerfEventListener(PerfEventListener listener);
public PerfEventListener getPerfEventListener();
} }

View File

@ -1,20 +1,19 @@
/** /**
*
* Copyright 2005-2006 The Apache Software Foundation * Copyright 2005-2006 The Apache Software Foundation
* * <p/>
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* * <p/>
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* * <p/>
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.activemq.tool; package org.apache.activemq.tool.properties;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -22,17 +21,25 @@ import org.apache.commons.logging.LogFactory;
import java.util.Iterator; import java.util.Iterator;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.Properties; import java.util.Properties;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public final class ReflectionUtil { public final class ReflectionUtil {
private static final Log log = LogFactory.getLog(ReflectionUtil.class); private static final Log log = LogFactory.getLog(ReflectionUtil.class);
private ReflectionUtil() { private ReflectionUtil() {
} }
public static void configureClass(Object obj, String key, String val) { public static void configureClass(Object obj, String key, String val) {
// Check if we will recognize the property first
if (obj instanceof ReflectionConfigurable && !((ReflectionConfigurable)obj).acceptConfig(key, val)) {
return;
}
try { try {
String debugInfo; String debugInfo;
@ -45,16 +52,13 @@ public final class ReflectionUtil {
StringTokenizer tokenizer = new StringTokenizer(key, "."); StringTokenizer tokenizer = new StringTokenizer(key, ".");
int tokenCount = tokenizer.countTokens(); int tokenCount = tokenizer.countTokens();
// NOTE: Skip the first token, it is assume that this is an indicator for the object itself
tokenizer.nextToken();
// For nested settings, get the object first. -2, do not count the first and last token // For nested settings, get the object first. -2, do not count the first and last token
for (int j=0; j<tokenCount-2; j++) { for (int j=0; j<tokenCount-1; j++) {
// Find getter method first // Find getter method first
String name = tokenizer.nextToken(); String name = tokenizer.nextToken();
String getMethod = "get" + name.substring(0,1).toUpperCase() + name.substring(1); String getMethod = "get" + name.substring(0,1).toUpperCase() + name.substring(1);
Method method = targetClass.getMethod(getMethod, new Class[] {}); Method method = targetClass.getMethod(getMethod, new Class[] {});
target = method.invoke(target, (Object[])null); target = method.invoke(target, null);
targetClass = target.getClass(); targetClass = target.getClass();
debugInfo += ("." + getMethod + "()"); debugInfo += ("." + getMethod + "()");
@ -111,10 +115,92 @@ public final class ReflectionUtil {
public static void configureClass(Object obj, Properties props) { public static void configureClass(Object obj, Properties props) {
for (Iterator i = props.keySet().iterator(); i.hasNext();) { for (Iterator i = props.keySet().iterator(); i.hasNext();) {
try {
String key = (String)i.next(); String key = (String)i.next();
String val = props.getProperty(key); String val = props.getProperty(key);
configureClass(obj, key, val); configureClass(obj, key, val);
} catch (Throwable t) {
// Let's catch any exception as this could be cause by the foreign class
t.printStackTrace();
}
}
}
public static Properties retrieveObjectProperties(Object obj) {
Properties props = new Properties();
try {
props.putAll(retrieveClassProperties("", obj.getClass(), obj));
} catch (Exception e) {
log.warn(e);
}
return props;
}
protected static Properties retrieveClassProperties(String prefix, Class targetClass, Object targetObject) {
if (targetClass == null || targetObject == null) {
return new Properties();
} else {
Properties props = new Properties();
Field[] fields = getAllFields(targetClass);
Method getterMethod;
for (int i=0; i<fields.length; i++) {
try {
if ((getterMethod = isPropertyField(targetClass, fields[i])) != null) {
if (fields[i].getType().isPrimitive() || fields[i].getType() == String.class) {
Object val = null;
try {
val = getterMethod.invoke(targetObject, null);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
props.setProperty(prefix + fields[i].getName(), val + "");
} else {
try {
Object val = getterMethod.invoke(targetObject, null);
if (val != null) {
props.putAll(retrieveClassProperties(fields[i].getName() + ".", val.getClass(), val));
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
} catch (Throwable t) {
// Let's catch any exception, cause this could be cause by the foreign class
t.printStackTrace();
}
}
return props;
}
}
protected static Method isPropertyField(Class targetClass, Field targetField) {
String fieldName = targetField.getName();
String getMethod = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
String isMethod = "is" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
String setMethod = "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
// Check setter method
try {
targetClass.getMethod(setMethod, new Class[]{targetField.getType()});
} catch (NoSuchMethodException e) {
return null;
}
// Check getter method and return it if it exists
try {
return targetClass.getMethod(getMethod, null);
} catch (NoSuchMethodException e1) {
try {
return targetClass.getMethod(isMethod, null);
} catch (NoSuchMethodException e2) {
return null;
}
} }
} }
@ -128,4 +214,13 @@ public final class ReflectionUtil {
} }
throw new NoSuchFieldException(fieldName); throw new NoSuchFieldException(fieldName);
} }
public static Field[] getAllFields(Class targetClass) {
List fieldList = new ArrayList();
while (targetClass != null) {
Collections.addAll(fieldList, targetClass.getDeclaredFields());
targetClass = targetClass.getSuperclass();
}
return (Field[])fieldList.toArray(new Field[0]);
}
} }

View File

@ -16,178 +16,23 @@
*/ */
package org.apache.activemq.tool.reports; package org.apache.activemq.tool.reports;
import org.apache.activemq.tool.ReflectionUtil; import org.apache.activemq.tool.reports.plugins.ReportPlugin;
import org.apache.activemq.tool.reports.plugins.ThroughputReportPlugin;
import org.apache.activemq.tool.reports.plugins.CpuReportPlugin;
import java.util.Properties;
import java.util.Map; import java.util.Map;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.Iterator;
public abstract class AbstractPerfReportWriter implements PerformanceReportWriter { public abstract class AbstractPerfReportWriter implements PerformanceReportWriter {
public static final String KEY_SYS_TOTAL_TP = "SystemTotalTP"; protected ReportPlugin[] plugins = new ReportPlugin[] {
public static final String KEY_SYS_TOTAL_CLIENTS = "SystemTotalClients"; new ThroughputReportPlugin(),
public static final String KEY_SYS_AVE_TP = "SystemAveTP"; new CpuReportPlugin()
public static final String KEY_SYS_AVE_EMM_TP = "SystemAveEMMTP"; };
public static final String KEY_SYS_AVE_CLIENT_TP = "SystemAveClientTP";
public static final String KEY_SYS_AVE_CLIENT_EMM_TP = "SystemAveClientEMMTP";
public static final String KEY_MIN_CLIENT_TP = "MinClientTP";
public static final String KEY_MAX_CLIENT_TP = "MaxClientTP";
public static final String KEY_MIN_CLIENT_TOTAL_TP = "MinClientTotalTP";
public static final String KEY_MAX_CLIENT_TOTAL_TP = "MaxClientTotalTP";
public static final String KEY_MIN_CLIENT_AVE_TP = "MinClientAveTP";
public static final String KEY_MAX_CLIENT_AVE_TP = "MaxClientAveTP";
public static final String KEY_MIN_CLIENT_AVE_EMM_TP = "MinClientAveEMMTP";
public static final String KEY_MAX_CLIENT_AVE_EMM_TP = "MaxClientAveEMMTP";
protected Properties settings; protected void handleCsvData(int pluginType, String csvData) {
protected Map clientThroughputs = new HashMap(); plugins[pluginType].handleCsvData(csvData);
public void setSettings(Properties settings) {
this.settings = settings;
ReflectionUtil.configureClass(this, settings);
} }
public Properties getSettings() { protected Map getSummary(int pluginType) {
return settings; return plugins[pluginType].getSummary();
}
protected void parsePerfCsvData(String csvData) {
StringTokenizer tokenizer = new StringTokenizer(csvData, ",");
String data, key, val, clientName = null;
Long throughput = null;
while (tokenizer.hasMoreTokens()) {
data = tokenizer.nextToken();
key = data.substring(0, data.indexOf("="));
val = data.substring(data.indexOf("=") + 1);
if (key.equalsIgnoreCase("clientName")) {
clientName = val;
} else if (key.equalsIgnoreCase("throughput")) {
throughput = Long.valueOf(val);
} else {
// Ignore unknown token
}
}
addToClientTPList(clientName, throughput);
}
protected void addToClientTPList(String clientName, Long throughput) {
// Write to client's throughput list
if (clientName == null || throughput == null) {
throw new IllegalArgumentException("Invalid Throughput CSV Data: clientName=" + clientName + ", throughput=" + throughput);
}
List clientTPList = (List)clientThroughputs.get(clientName);
if (clientTPList == null) {
clientTPList = new ArrayList();
clientThroughputs.put(clientName, clientTPList);
}
clientTPList.add(throughput);
}
protected Map createPerfSummary(Map clientTPMap) {
long minClientTP = Long.MAX_VALUE, // TP = throughput
maxClientTP = Long.MIN_VALUE,
minClientTotalTP = Long.MAX_VALUE,
maxClientTotalTP = Long.MIN_VALUE,
systemTotalTP = 0;
double minClientAveTP = Double.MAX_VALUE,
maxClientAveTP = Double.MIN_VALUE,
minClientAveEMMTP = Double.MAX_VALUE, // EMM = Excluding Min/Max
maxClientAveEMMTP = Double.MIN_VALUE,
systemAveTP = 0.0,
systemAveEMMTP = 0.0;
String nameMinClientTP = "",
nameMaxClientTP = "",
nameMinClientTotalTP = "",
nameMaxClientTotalTP = "",
nameMinClientAveTP = "",
nameMaxClientAveTP = "",
nameMinClientAveEMMTP = "",
nameMaxClientAveEMMTP = "";
Set clientNames = clientTPMap.keySet();
String clientName;
List clientTPList;
long tempLong;
double tempDouble;
int clientCount = 0;
for (Iterator i=clientNames.iterator(); i.hasNext();) {
clientName = (String)i.next();
clientTPList = (List)clientTPMap.get(clientName);
clientCount++;
tempLong = PerformanceStatisticsUtil.getMinThroughput(clientTPList);
if (tempLong < minClientTP) {
minClientTP = tempLong;
nameMinClientTP = clientName;
}
tempLong = PerformanceStatisticsUtil.getMaxThroughput(clientTPList);
if (tempLong > maxClientTP) {
maxClientTP = tempLong;
nameMaxClientTP = clientName;
}
tempLong = PerformanceStatisticsUtil.getTotalThroughput(clientTPList);
systemTotalTP += tempLong; // Accumulate total TP
if (tempLong < minClientTotalTP) {
minClientTotalTP = tempLong;
nameMinClientTotalTP = clientName;
}
if (tempLong > maxClientTotalTP) {
maxClientTotalTP = tempLong;
nameMaxClientTotalTP = clientName;
}
tempDouble = PerformanceStatisticsUtil.getAveThroughput(clientTPList);
systemAveTP += tempDouble; // Accumulate ave throughput
if (tempDouble < minClientAveTP) {
minClientAveTP = tempDouble;
nameMinClientAveTP = clientName;
}
if (tempDouble > maxClientAveTP) {
maxClientAveTP = tempDouble;
nameMaxClientAveTP = clientName;
}
tempDouble = PerformanceStatisticsUtil.getAveThroughputExcludingMinMax(clientTPList);
systemAveEMMTP += tempDouble; // Accumulate ave throughput excluding min/max
if (tempDouble < minClientAveEMMTP) {
minClientAveEMMTP = tempDouble;
nameMinClientAveEMMTP = clientName;
}
if (tempDouble > maxClientAveEMMTP) {
maxClientAveEMMTP = tempDouble;
nameMaxClientAveEMMTP = clientName;
}
}
Map summary = new HashMap();
summary.put(KEY_SYS_TOTAL_TP, String.valueOf(systemTotalTP));
summary.put(KEY_SYS_TOTAL_CLIENTS, String.valueOf(clientCount));
summary.put(KEY_SYS_AVE_TP, String.valueOf(systemAveTP));
summary.put(KEY_SYS_AVE_EMM_TP, String.valueOf(systemAveEMMTP));
summary.put(KEY_SYS_AVE_CLIENT_TP, String.valueOf(systemAveTP / clientCount));
summary.put(KEY_SYS_AVE_CLIENT_EMM_TP, String.valueOf(systemAveEMMTP / clientCount));
summary.put(KEY_MIN_CLIENT_TP, nameMinClientTP + "=" + minClientTP);
summary.put(KEY_MAX_CLIENT_TP, nameMaxClientTP + "=" + maxClientTP);
summary.put(KEY_MIN_CLIENT_TOTAL_TP, nameMinClientTotalTP + "=" + minClientTotalTP);
summary.put(KEY_MAX_CLIENT_TOTAL_TP, nameMaxClientTotalTP + "=" + maxClientTotalTP);
summary.put(KEY_MIN_CLIENT_AVE_TP, nameMinClientAveTP + "=" + minClientAveTP);
summary.put(KEY_MAX_CLIENT_AVE_TP, nameMaxClientAveTP + "=" + maxClientAveTP);
summary.put(KEY_MIN_CLIENT_AVE_EMM_TP, nameMinClientAveEMMTP + "=" + minClientAveEMMTP);
summary.put(KEY_MAX_CLIENT_AVE_EMM_TP, nameMaxClientAveEMMTP + "=" + maxClientAveEMMTP);
return summary;
} }
} }

View File

@ -19,12 +19,10 @@ package org.apache.activemq.tool.reports;
import java.util.Properties; import java.util.Properties;
public interface PerformanceReportWriter { public interface PerformanceReportWriter {
public void setSettings(Properties settings);
public Properties getSettings();
public void openReportWriter(); public void openReportWriter();
public void closeReportWriter(); public void closeReportWriter();
public void writeInfo(String info); public void writeInfo(String info);
public void writePerfData(String data); public void writeCsvData(int csvType, String csvData);
public void writeProperties(String header, Properties props); public void writeProperties(String header, Properties props);
public void writeProperties(Properties props); public void writeProperties(Properties props);
} }

View File

@ -16,6 +16,9 @@
*/ */
package org.apache.activemq.tool.reports; package org.apache.activemq.tool.reports;
import org.apache.activemq.tool.reports.plugins.ReportPlugin;
import org.apache.activemq.tool.reports.plugins.ThroughputReportPlugin;
import java.util.Properties; import java.util.Properties;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -24,7 +27,7 @@ import java.util.Arrays;
public class VerbosePerfReportWriter extends AbstractPerfReportWriter { public class VerbosePerfReportWriter extends AbstractPerfReportWriter {
public void openReportWriter() { public void openReportWriter() {
writeProperties("System Properties", System.getProperties()); // Do nothing
} }
public void closeReportWriter() { public void closeReportWriter() {
@ -36,20 +39,13 @@ public class VerbosePerfReportWriter extends AbstractPerfReportWriter {
System.out.println("[PERF-INFO]: " + info); System.out.println("[PERF-INFO]: " + info);
} }
public void writeHeader(String header) { public void writeCsvData(int csvType, String csvData) {
char[] border = new char[header.length() + 8]; // +8 for spacing if (csvType == ReportPlugin.REPORT_PLUGIN_THROUGHPUT) {
Arrays.fill(border, '#'); System.out.println("[PERF-TP]: " + csvData);
String borderStr = new String(border); } else if (csvType == ReportPlugin.REPORT_PLUGIN_CPU) {
System.out.println("[PERF-CPU]: " + csvData);
System.out.println(borderStr);
System.out.println("# " + header + " #");
System.out.println(borderStr);
} }
handleCsvData(csvType, csvData);
public void writePerfData(String data) {
System.out.println("[PERF-DATA]: " + data);
// Assume data is a CSV of key-value pair
parsePerfCsvData(data);
} }
public void writeProperties(String header, Properties props) { public void writeProperties(String header, Properties props) {
@ -66,22 +62,32 @@ public class VerbosePerfReportWriter extends AbstractPerfReportWriter {
} }
public void writePerfSummary() { public void writePerfSummary() {
Map summary = createPerfSummary(clientThroughputs); Map summary = getSummary(ReportPlugin.REPORT_PLUGIN_THROUGHPUT);
System.out.println("[PERF-SUMMARY] System Total Throughput: " + summary.get(KEY_SYS_TOTAL_TP)); System.out.println("[PERF-TP-SUMMARY] System Total Throughput: " + summary.get(ThroughputReportPlugin.KEY_SYS_TOTAL_TP));
System.out.println("[PERF-SUMMARY] System Total Clients: " + summary.get(KEY_SYS_TOTAL_CLIENTS)); System.out.println("[PERF-TP-SUMMARY] System Total Clients: " + summary.get(ThroughputReportPlugin.KEY_SYS_TOTAL_CLIENTS));
System.out.println("[PERF-SUMMARY] System Average Throughput: " + summary.get(KEY_SYS_AVE_TP)); System.out.println("[PERF-TP-SUMMARY] System Average Throughput: " + summary.get(ThroughputReportPlugin.KEY_SYS_AVE_TP));
System.out.println("[PERF-SUMMARY] System Average Throughput Excluding Min/Max: " + summary.get(KEY_SYS_AVE_EMM_TP)); System.out.println("[PERF-TP-SUMMARY] System Average Throughput Excluding Min/Max: " + summary.get(ThroughputReportPlugin.KEY_SYS_AVE_EMM_TP));
System.out.println("[PERF-SUMMARY] System Average Client Throughput: " + summary.get(KEY_SYS_AVE_CLIENT_TP)); System.out.println("[PERF-TP-SUMMARY] System Average Client Throughput: " + summary.get(ThroughputReportPlugin.KEY_SYS_AVE_CLIENT_TP));
System.out.println("[PERF-SUMMARY] System Average Client Throughput Excluding Min/Max: " + summary.get(KEY_SYS_AVE_CLIENT_EMM_TP)); System.out.println("[PERF-TP-SUMMARY] System Average Client Throughput Excluding Min/Max: " + summary.get(ThroughputReportPlugin.KEY_SYS_AVE_CLIENT_EMM_TP));
System.out.println("[PERF-SUMMARY] Min Client Throughput Per Sample: " + summary.get(KEY_MIN_CLIENT_TP)); System.out.println("[PERF-TP-SUMMARY] Min Client Throughput Per Sample: " + summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_TP));
System.out.println("[PERF-SUMMARY] Max Client Throughput Per Sample: " + summary.get(KEY_MAX_CLIENT_TP)); System.out.println("[PERF-TP-SUMMARY] Max Client Throughput Per Sample: " + summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_TP));
System.out.println("[PERF-SUMMARY] Min Client Total Throughput: " + summary.get(KEY_MIN_CLIENT_TOTAL_TP)); System.out.println("[PERF-TP-SUMMARY] Min Client Total Throughput: " + summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_TOTAL_TP));
System.out.println("[PERF-SUMMARY] Max Client Total Throughput: " + summary.get(KEY_MAX_CLIENT_TOTAL_TP)); System.out.println("[PERF-TP-SUMMARY] Max Client Total Throughput: " + summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_TOTAL_TP));
System.out.println("[PERF-SUMMARY] Min Client Average Throughput: " + summary.get(KEY_MIN_CLIENT_AVE_TP)); System.out.println("[PERF-TP-SUMMARY] Min Client Average Throughput: " + summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_AVE_TP));
System.out.println("[PERF-SUMMARY] Max Client Average Throughput: " + summary.get(KEY_MAX_CLIENT_AVE_TP)); System.out.println("[PERF-TP-SUMMARY] Max Client Average Throughput: " + summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_AVE_TP));
System.out.println("[PERF-SUMMARY] Min Client Average Throughput Excluding Min/Max: " + summary.get(KEY_MIN_CLIENT_AVE_EMM_TP)); System.out.println("[PERF-TP-SUMMARY] Min Client Average Throughput Excluding Min/Max: " + summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_AVE_EMM_TP));
System.out.println("[PERF-SUMMARY] Max Client Average Throughput Excluding Min/Max: " + summary.get(KEY_MAX_CLIENT_AVE_EMM_TP)); System.out.println("[PERF-TP-SUMMARY] Max Client Average Throughput Excluding Min/Max: " + summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_AVE_EMM_TP));
}
protected void writeHeader(String header) {
char[] border = new char[header.length() + 8]; // +8 for spacing
Arrays.fill(border, '#');
String borderStr = new String(border);
System.out.println(borderStr);
System.out.println("# " + header + " #");
System.out.println(borderStr);
} }
} }

View File

@ -18,6 +18,8 @@ package org.apache.activemq.tool.reports;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.activemq.tool.reports.plugins.ReportPlugin;
import org.apache.activemq.tool.reports.plugins.ThroughputReportPlugin;
import java.util.Properties; import java.util.Properties;
import java.util.List; import java.util.List;
@ -99,12 +101,24 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
this.reportName = reportName; this.reportName = reportName;
} }
public File getXmlFile() {
return xmlFile;
}
public void setXmlFile(File xmlFile) {
this.xmlFile = xmlFile;
}
public void writeInfo(String info) { public void writeInfo(String info) {
tempLogFileWriter.println("[INFO]" + info); tempLogFileWriter.println("[INFO]" + info);
} }
public void writePerfData(String data) { public void writeCsvData(int csvType, String csvData) {
tempLogFileWriter.println("[DATA]" + data); if (csvType == ReportPlugin.REPORT_PLUGIN_THROUGHPUT) {
tempLogFileWriter.println("[TP-DATA]" + csvData);
} else if (csvType == ReportPlugin.REPORT_PLUGIN_CPU) {
tempLogFileWriter.println("[CPU-DATA]" + csvData);
}
} }
public void writeProperties(String header, Properties props) { public void writeProperties(String header, Properties props) {
@ -116,7 +130,7 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
} }
protected File createTempLogFile() { protected File createTempLogFile() {
File f = null; File f;
try { try {
f = File.createTempFile("tmpPL", null); f = File.createTempFile("tmpPL", null);
} catch (IOException e) { } catch (IOException e) {
@ -130,8 +144,7 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
String filename = (getReportName().endsWith(".xml") ? getReportName() : (getReportName() + ".xml")); String filename = (getReportName().endsWith(".xml") ? getReportName() : (getReportName() + ".xml"));
String path = (getReportDir() == null) ? "" : getReportDir(); String path = (getReportDir() == null) ? "" : getReportDir();
File f = new File(path + filename); return new File(path + filename);
return f;
} }
protected void writeToXml() { protected void writeToXml() {
@ -145,7 +158,7 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
writeXmlFooter(); writeXmlFooter();
xmlFileWriter.close(); xmlFileWriter.close();
System.out.println("Created performance report: " + xmlFile.getAbsolutePath()); log.info("Created performance report: " + xmlFile.getAbsolutePath());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -161,8 +174,6 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
protected void writeXmlTestSettings() { protected void writeXmlTestSettings() {
Properties props; Properties props;
// Write system settings
writeMap("systemSettings", System.getProperties());
// Write test settings // Write test settings
for (Iterator i=testPropsMap.keySet().iterator(); i.hasNext();) { for (Iterator i=testPropsMap.keySet().iterator(); i.hasNext();) {
@ -186,12 +197,16 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(tempLogFile))); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(tempLogFile)));
String line; String line;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
if (line.startsWith("[DATA]")) { if (line.startsWith("[TP-DATA]")) {
parsePerfCsvData(line.substring("[DATA]".length())); handleCsvData(ReportPlugin.REPORT_PLUGIN_THROUGHPUT, line.substring("[TP-DATA]".length()));
parsePerfCsvData("tpdata", line.substring("[TP-DATA]".length()));
} else if (line.startsWith("[CPU-DATA]")) {
handleCsvData(ReportPlugin.REPORT_PLUGIN_CPU, line.substring("[CPU-DATA]".length()));
parsePerfCsvData("cpudata", line.substring("[CPU-DATA]".length()));
} else if (line.startsWith("[INFO]")) { } else if (line.startsWith("[INFO]")) {
xmlFileWriter.println("<value>" + line + "</value>"); xmlFileWriter.println("<info>" + line + "</info>");
} else { } else {
xmlFileWriter.println("<value>[ERROR]" + line + "</value>"); xmlFileWriter.println("<error>" + line + "</error>");
} }
} }
@ -200,84 +215,85 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
} }
protected void writeXmlPerfSummary() { protected void writeXmlPerfSummary() {
Map summary = createPerfSummary(clientThroughputs); // Write throughput summary
Map summary = getSummary(ReportPlugin.REPORT_PLUGIN_THROUGHPUT);
xmlFileWriter.println("<property name='perfSummary'>"); xmlFileWriter.println("<property name='perfSummary'>");
xmlFileWriter.println("<props>"); xmlFileWriter.println("<props>");
String val, clientName, clientVal; String val, clientName, clientVal;
val = (String)summary.get(KEY_SYS_TOTAL_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_SYS_TOTAL_TP);
System.out.println("System Total Throughput: " + val); System.out.println("System Total Throughput: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_TOTAL_TP + "'>" + val + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_SYS_TOTAL_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_TOTAL_CLIENTS); val = (String)summary.get(ThroughputReportPlugin.KEY_SYS_TOTAL_CLIENTS);
System.out.println("System Total Clients: " + val); System.out.println("System Total Clients: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_TOTAL_CLIENTS + "'>" + val + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_SYS_TOTAL_CLIENTS + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_AVE_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_SYS_AVE_TP);
System.out.println("System Average Throughput: " + val); System.out.println("System Average Throughput: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_AVE_TP + "'>" + val + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_SYS_AVE_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_AVE_EMM_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_SYS_AVE_EMM_TP);
System.out.println("System Average Throughput Excluding Min/Max: " + val); System.out.println("System Average Throughput Excluding Min/Max: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_AVE_EMM_TP + "'>" + val + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_SYS_AVE_EMM_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_AVE_CLIENT_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_SYS_AVE_CLIENT_TP);
System.out.println("System Average Client Throughput: " + val); System.out.println("System Average Client Throughput: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_AVE_CLIENT_TP + "'>" + val + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_SYS_AVE_CLIENT_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_SYS_AVE_CLIENT_EMM_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_SYS_AVE_CLIENT_EMM_TP);
System.out.println("System Average Client Throughput Excluding Min/Max: " + val); System.out.println("System Average Client Throughput Excluding Min/Max: " + val);
xmlFileWriter.println("<prop key='" + KEY_SYS_AVE_CLIENT_EMM_TP + "'>" + val + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_SYS_AVE_CLIENT_EMM_TP + "'>" + val + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Client Throughput Per Sample: clientName=" + clientName + ", value=" + clientVal); System.out.println("Min Client Throughput Per Sample: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MIN_CLIENT_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Client Throughput Per Sample: clientName=" + clientName + ", value=" + clientVal); System.out.println("Max Client Throughput Per Sample: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MAX_CLIENT_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_TOTAL_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_TOTAL_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Client Total Throughput: clientName=" + clientName + ", value=" + clientVal); System.out.println("Min Client Total Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_TOTAL_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MIN_CLIENT_TOTAL_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_TOTAL_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_TOTAL_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Client Total Throughput: clientName=" + clientName + ", value=" + clientVal); System.out.println("Max Client Total Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_TOTAL_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MAX_CLIENT_TOTAL_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_AVE_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_AVE_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Average Client Throughput: clientName=" + clientName + ", value=" + clientVal); System.out.println("Min Average Client Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_AVE_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MIN_CLIENT_AVE_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_AVE_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_AVE_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Average Client Throughput: clientName=" + clientName + ", value=" + clientVal); System.out.println("Max Average Client Throughput: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_AVE_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MAX_CLIENT_AVE_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MIN_CLIENT_AVE_EMM_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MIN_CLIENT_AVE_EMM_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Min Average Client Throughput Excluding Min/Max: clientName=" + clientName + ", value=" + clientVal); System.out.println("Min Average Client Throughput Excluding Min/Max: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MIN_CLIENT_AVE_EMM_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MIN_CLIENT_AVE_EMM_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
val = (String)summary.get(KEY_MAX_CLIENT_AVE_EMM_TP); val = (String)summary.get(ThroughputReportPlugin.KEY_MAX_CLIENT_AVE_EMM_TP);
clientName = val.substring(0, val.indexOf("=")); clientName = val.substring(0, val.indexOf("="));
clientVal = val.substring(val.indexOf("=") + 1); clientVal = val.substring(val.indexOf("=") + 1);
System.out.println("Max Average Client Throughput Excluding Min/Max: clientName=" + clientName + ", value=" + clientVal); System.out.println("Max Average Client Throughput Excluding Min/Max: clientName=" + clientName + ", value=" + clientVal);
xmlFileWriter.println("<prop key='" + KEY_MAX_CLIENT_AVE_EMM_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>"); xmlFileWriter.println("<prop key='" + ThroughputReportPlugin.KEY_MAX_CLIENT_AVE_EMM_TP + "'>clientName=" + clientName + ",value=" + clientVal + "</prop>");
xmlFileWriter.println("</props>"); xmlFileWriter.println("</props>");
xmlFileWriter.println("</property>"); xmlFileWriter.println("</property>");
@ -295,26 +311,19 @@ public class XmlFilePerfReportWriter extends AbstractPerfReportWriter {
xmlFileWriter.println("</property>"); xmlFileWriter.println("</property>");
} }
protected void parsePerfCsvData(String csvData) { protected void parsePerfCsvData(String elementName, String csvData) {
StringTokenizer tokenizer = new StringTokenizer(csvData, ","); StringTokenizer tokenizer = new StringTokenizer(csvData, ",");
String data, key, val, clientName = null; String xmlElement;
Long throughput = null;
int index = -1; xmlElement = "<" + elementName;
String data, key, val;
while (tokenizer.hasMoreTokens()) { while (tokenizer.hasMoreTokens()) {
data = tokenizer.nextToken(); data = tokenizer.nextToken();
key = data.substring(0, data.indexOf("=")); key = data.substring(0, data.indexOf("="));
val = data.substring(data.indexOf("=") + 1); val = data.substring(data.indexOf("=") + 1);
xmlElement += (" " + key + "='" + val + "'");
if (key.equalsIgnoreCase("clientName")) {
clientName = val;
} else if (key.equalsIgnoreCase("throughput")) {
throughput = Long.valueOf(val);
} else if (key.equalsIgnoreCase("index")) {
index = Integer.parseInt(val);
} }
} xmlElement += " />";
addToClientTPList(clientName, throughput); xmlFileWriter.println(xmlElement);
xmlFileWriter.println("<value index='" + index + "' clientName='" + clientName +
"'>" + throughput.longValue() + "</value>");
} }
} }

View File

@ -0,0 +1,29 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.reports.plugins;
import java.util.Map;
public class CpuReportPlugin implements ReportPlugin {
public void handleCsvData(String csvData) {
// Do nothing
}
public Map getSummary() {
return null; // Do nothing
}
}

View File

@ -0,0 +1,27 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.reports.plugins;
import java.util.Map;
public interface ReportPlugin {
public static final int REPORT_PLUGIN_THROUGHPUT = 0;
public static final int REPORT_PLUGIN_CPU = 1;
public void handleCsvData(String csvData);
public Map getSummary();
}

View File

@ -0,0 +1,182 @@
/**
*
* Copyright 2005-2006 The Apache Software Foundation
*
* Licensed 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.activemq.tool.reports.plugins;
import org.apache.activemq.tool.reports.PerformanceStatisticsUtil;
import java.util.Map;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.Iterator;
public class ThroughputReportPlugin implements ReportPlugin {
public static final String KEY_SYS_TOTAL_TP = "SystemTotalTP";
public static final String KEY_SYS_TOTAL_CLIENTS = "SystemTotalClients";
public static final String KEY_SYS_AVE_TP = "SystemAveTP";
public static final String KEY_SYS_AVE_EMM_TP = "SystemAveEMMTP";
public static final String KEY_SYS_AVE_CLIENT_TP = "SystemAveClientTP";
public static final String KEY_SYS_AVE_CLIENT_EMM_TP = "SystemAveClientEMMTP";
public static final String KEY_MIN_CLIENT_TP = "MinClientTP";
public static final String KEY_MAX_CLIENT_TP = "MaxClientTP";
public static final String KEY_MIN_CLIENT_TOTAL_TP = "MinClientTotalTP";
public static final String KEY_MAX_CLIENT_TOTAL_TP = "MaxClientTotalTP";
public static final String KEY_MIN_CLIENT_AVE_TP = "MinClientAveTP";
public static final String KEY_MAX_CLIENT_AVE_TP = "MaxClientAveTP";
public static final String KEY_MIN_CLIENT_AVE_EMM_TP = "MinClientAveEMMTP";
public static final String KEY_MAX_CLIENT_AVE_EMM_TP = "MaxClientAveEMMTP";
protected Map clientThroughputs = new HashMap();
public void handleCsvData(String csvData) {
StringTokenizer tokenizer = new StringTokenizer(csvData, ",");
String data, key, val, clientName = null;
Long throughput = null;
while (tokenizer.hasMoreTokens()) {
data = tokenizer.nextToken();
key = data.substring(0, data.indexOf("="));
val = data.substring(data.indexOf("=") + 1);
if (key.equalsIgnoreCase("clientName")) {
clientName = val;
} else if (key.equalsIgnoreCase("throughput")) {
throughput = Long.valueOf(val);
} else {
// Ignore unknown token
}
}
addToClientTPList(clientName, throughput);
}
public Map getSummary() {
long minClientTP = Long.MAX_VALUE, // TP = throughput
maxClientTP = Long.MIN_VALUE,
minClientTotalTP = Long.MAX_VALUE,
maxClientTotalTP = Long.MIN_VALUE,
systemTotalTP = 0;
double minClientAveTP = Double.MAX_VALUE,
maxClientAveTP = Double.MIN_VALUE,
minClientAveEMMTP = Double.MAX_VALUE, // EMM = Excluding Min/Max
maxClientAveEMMTP = Double.MIN_VALUE,
systemAveTP = 0.0,
systemAveEMMTP = 0.0;
String nameMinClientTP = "",
nameMaxClientTP = "",
nameMinClientTotalTP = "",
nameMaxClientTotalTP = "",
nameMinClientAveTP = "",
nameMaxClientAveTP = "",
nameMinClientAveEMMTP = "",
nameMaxClientAveEMMTP = "";
Set clientNames = clientThroughputs.keySet();
String clientName;
List clientTPList;
long tempLong;
double tempDouble;
int clientCount = 0;
for (Iterator i=clientNames.iterator(); i.hasNext();) {
clientName = (String)i.next();
clientTPList = (List)clientThroughputs.get(clientName);
clientCount++;
tempLong = PerformanceStatisticsUtil.getMinThroughput(clientTPList);
if (tempLong < minClientTP) {
minClientTP = tempLong;
nameMinClientTP = clientName;
}
tempLong = PerformanceStatisticsUtil.getMaxThroughput(clientTPList);
if (tempLong > maxClientTP) {
maxClientTP = tempLong;
nameMaxClientTP = clientName;
}
tempLong = PerformanceStatisticsUtil.getTotalThroughput(clientTPList);
systemTotalTP += tempLong; // Accumulate total TP
if (tempLong < minClientTotalTP) {
minClientTotalTP = tempLong;
nameMinClientTotalTP = clientName;
}
if (tempLong > maxClientTotalTP) {
maxClientTotalTP = tempLong;
nameMaxClientTotalTP = clientName;
}
tempDouble = PerformanceStatisticsUtil.getAveThroughput(clientTPList);
systemAveTP += tempDouble; // Accumulate ave throughput
if (tempDouble < minClientAveTP) {
minClientAveTP = tempDouble;
nameMinClientAveTP = clientName;
}
if (tempDouble > maxClientAveTP) {
maxClientAveTP = tempDouble;
nameMaxClientAveTP = clientName;
}
tempDouble = PerformanceStatisticsUtil.getAveThroughputExcludingMinMax(clientTPList);
systemAveEMMTP += tempDouble; // Accumulate ave throughput excluding min/max
if (tempDouble < minClientAveEMMTP) {
minClientAveEMMTP = tempDouble;
nameMinClientAveEMMTP = clientName;
}
if (tempDouble > maxClientAveEMMTP) {
maxClientAveEMMTP = tempDouble;
nameMaxClientAveEMMTP = clientName;
}
}
Map summary = new HashMap();
summary.put(KEY_SYS_TOTAL_TP, String.valueOf(systemTotalTP));
summary.put(KEY_SYS_TOTAL_CLIENTS, String.valueOf(clientCount));
summary.put(KEY_SYS_AVE_TP, String.valueOf(systemAveTP));
summary.put(KEY_SYS_AVE_EMM_TP, String.valueOf(systemAveEMMTP));
summary.put(KEY_SYS_AVE_CLIENT_TP, String.valueOf(systemAveTP / clientCount));
summary.put(KEY_SYS_AVE_CLIENT_EMM_TP, String.valueOf(systemAveEMMTP / clientCount));
summary.put(KEY_MIN_CLIENT_TP, nameMinClientTP + "=" + minClientTP);
summary.put(KEY_MAX_CLIENT_TP, nameMaxClientTP + "=" + maxClientTP);
summary.put(KEY_MIN_CLIENT_TOTAL_TP, nameMinClientTotalTP + "=" + minClientTotalTP);
summary.put(KEY_MAX_CLIENT_TOTAL_TP, nameMaxClientTotalTP + "=" + maxClientTotalTP);
summary.put(KEY_MIN_CLIENT_AVE_TP, nameMinClientAveTP + "=" + minClientAveTP);
summary.put(KEY_MAX_CLIENT_AVE_TP, nameMaxClientAveTP + "=" + maxClientAveTP);
summary.put(KEY_MIN_CLIENT_AVE_EMM_TP, nameMinClientAveEMMTP + "=" + minClientAveEMMTP);
summary.put(KEY_MAX_CLIENT_AVE_EMM_TP, nameMaxClientAveEMMTP + "=" + maxClientAveEMMTP);
return summary;
}
protected void addToClientTPList(String clientName, Long throughput) {
// Write to client's throughput list
if (clientName == null || throughput == null) {
throw new IllegalArgumentException("Invalid Throughput CSV Data: clientName=" + clientName + ", throughput=" + throughput);
}
List clientTPList = (List)clientThroughputs.get(clientName);
if (clientTPList == null) {
clientTPList = new ArrayList();
clientThroughputs.put(clientName, clientTPList);
}
clientTPList.add(throughput);
}
}

View File

@ -16,7 +16,7 @@
*/ */
package org.apache.activemq.tool.spi; package org.apache.activemq.tool.spi;
import org.apache.activemq.tool.ReflectionUtil; import org.apache.activemq.tool.properties.ReflectionUtil;
import javax.jms.ConnectionFactory; import javax.jms.ConnectionFactory;
import java.util.Properties; import java.util.Properties;

View File

@ -20,87 +20,160 @@ import junit.framework.TestCase;
import java.util.Properties; import java.util.Properties;
import org.apache.activemq.tool.properties.ReflectionUtil;
public class ReflectionUtilTest extends TestCase { public class ReflectionUtilTest extends TestCase {
private boolean booleanData;
private int intData;
private long longData;
private short shortData;
private double doubleData;
private float floatData;
private byte byteData;
private char charData;
private String stringData;
private ReflectionUtilTest testData; private ReflectionUtilTest testData;
private String data;
public void testDataTypeConfig() { public void testDataTypeConfig() {
// Initialize variables; TestClass3 targetObj = new TestClass3();
booleanData = false;
intData = 0;
longData = 0;
shortData = 0;
doubleData = 0.0;
floatData = 0.0F;
byteData = 0;
charData = '0';
stringData = "false";
Object targetObj = new ReflectionUtilTest(); // Initialize variables;
targetObj.setBooleanData(false);
targetObj.setIntData(0);
targetObj.setLongData(0);
targetObj.setShortData((short)0);
targetObj.setDoubleData(0.0);
targetObj.setFloatData(0.0F);
targetObj.setByteData((byte)0);
targetObj.setCharData('0');
targetObj.setStringData("false");
// Set properties // Set properties
Properties props = new Properties(); Properties props = new Properties();
props.setProperty("test.booleanData", "true"); props.setProperty("booleanData", "true");
props.setProperty("test.intData", "1000"); props.setProperty("intData", "1000");
props.setProperty("test.longData", "2000"); props.setProperty("longData", "2000");
props.setProperty("test.shortData", "3000"); props.setProperty("shortData", "3000");
props.setProperty("test.doubleData", "1234.567"); props.setProperty("doubleData", "1234.567");
props.setProperty("test.floatData", "9876.543"); props.setProperty("floatData", "9876.543");
props.setProperty("test.byteData", "127"); props.setProperty("byteData", "127");
props.setProperty("test.charData", "A"); props.setProperty("charData", "A");
props.setProperty("test.stringData", "true"); props.setProperty("stringData", "true");
props.setProperty("test.testData", "TEST.FOO.BAR");
ReflectionUtil.configureClass(targetObj, props); ReflectionUtil.configureClass(targetObj, props);
// Check config // Check config
assertEquals(true, ((ReflectionUtilTest)targetObj).isBooleanData()); assertEquals(true, targetObj.isBooleanData());
assertEquals(1000, ((ReflectionUtilTest)targetObj).getIntData()); assertEquals(1000, targetObj.getIntData());
assertEquals(2000, ((ReflectionUtilTest)targetObj).getLongData()); assertEquals(2000, targetObj.getLongData());
assertEquals(3000, ((ReflectionUtilTest)targetObj).getShortData()); assertEquals(3000, targetObj.getShortData());
assertEquals(1234.567, ((ReflectionUtilTest)targetObj).getDoubleData(), 0.0001); assertEquals(1234.567, targetObj.getDoubleData(), 0.0001);
assertEquals(9876.543, ((ReflectionUtilTest)targetObj).getFloatData(), 0.0001); assertEquals(9876.543, targetObj.getFloatData(), 0.0001);
assertEquals(127, ((ReflectionUtilTest)targetObj).getByteData()); assertEquals(127, targetObj.getByteData());
assertEquals('A', ((ReflectionUtilTest)targetObj).getCharData()); assertEquals('A', targetObj.getCharData());
assertEquals("true", ((ReflectionUtilTest)targetObj).getStringData()); assertEquals("true", targetObj.getStringData());
assertEquals("TEST.FOO.BAR", ((ReflectionUtilTest)targetObj).getTestData().getStringData()); }
public void testValueOfMethod() {
ReflectionUtilTest targetObj = new ReflectionUtilTest();
ReflectionUtil.configureClass(targetObj, "testData", "TEST.FOO.BAR");
assertEquals("TEST.FOO.BAR", targetObj.testData.data);
}
public void testGetProperties() {
TestClass3 testData = new TestClass3();
testData.setBooleanData(false);
testData.setByteData((byte)15);
testData.setCharData('G');
testData.setDoubleData(765.43);
testData.setFloatData(543.21F);
testData.setIntData(654321);
testData.setLongData(987654321);
testData.setShortData((short)4321);
testData.setStringData("BAR.TEST.FOO");
TestClass3 targetObj = new TestClass3();
targetObj.setBooleanData(true);
targetObj.setByteData((byte)10);
targetObj.setCharData('D');
targetObj.setDoubleData(1234.567);
targetObj.setFloatData(4567.89F);
targetObj.setIntData(123456);
targetObj.setLongData(1234567890);
targetObj.setShortData((short)1234);
targetObj.setStringData("Test.FOO.BAR");
targetObj.setTestData(testData);
Properties p = ReflectionUtil.retrieveObjectProperties(targetObj);
assertEquals("false", p.getProperty("testData.booleanData"));
assertEquals("15", p.getProperty("testData.byteData"));
assertEquals("G", p.getProperty("testData.charData"));
assertEquals("765.43", p.getProperty("testData.doubleData"));
assertEquals("543.21", p.getProperty("testData.floatData"));
assertEquals("654321", p.getProperty("testData.intData"));
assertEquals("987654321", p.getProperty("testData.longData"));
assertEquals("4321", p.getProperty("testData.shortData"));
assertEquals("BAR.TEST.FOO", p.getProperty("testData.stringData"));
assertEquals("true", p.getProperty("booleanData"));
assertEquals("10", p.getProperty("byteData"));
assertEquals("D", p.getProperty("charData"));
assertEquals("1234.567", p.getProperty("doubleData"));
assertEquals("4567.89", p.getProperty("floatData"));
assertEquals("123456", p.getProperty("intData"));
assertEquals("1234567890", p.getProperty("longData"));
assertEquals("1234", p.getProperty("shortData"));
assertEquals("Test.FOO.BAR", p.getProperty("stringData"));
} }
public void testNestedConfig() { public void testNestedConfig() {
ReflectionUtilTest t1 = new ReflectionUtilTest(); TestClass3 t1 = new TestClass3();
ReflectionUtilTest t2 = new ReflectionUtilTest(); TestClass3 t2 = new TestClass3();
ReflectionUtilTest t3 = new ReflectionUtilTest(); TestClass3 t3 = new TestClass3();
ReflectionUtilTest t4 = new ReflectionUtilTest(); TestClass3 t4 = new TestClass3();
ReflectionUtilTest t5 = new ReflectionUtilTest(); TestClass3 t5 = new TestClass3();
ReflectionUtil.configureClass(t1, "test.stringData", "t1"); ReflectionUtil.configureClass(t1, "stringData", "t1");
assertEquals("t1", t1.getStringData()); assertEquals("t1", t1.getStringData());
t1.setTestData(t2); t1.setTestData(t2);
ReflectionUtil.configureClass(t1, "test.testData.stringData", "t2"); ReflectionUtil.configureClass(t1, "testData.stringData", "t2");
assertEquals("t2", t2.getStringData()); assertEquals("t2", t2.getStringData());
t2.setTestData(t3); t2.setTestData(t3);
ReflectionUtil.configureClass(t1, "test.testData.testData.stringData", "t3"); ReflectionUtil.configureClass(t1, "testData.testData.stringData", "t3");
assertEquals("t3", t3.getStringData()); assertEquals("t3", t3.getStringData());
t3.setTestData(t4); t3.setTestData(t4);
ReflectionUtil.configureClass(t1, "test.testData.testData.testData.stringData", "t4"); ReflectionUtil.configureClass(t1, "testData.testData.testData.stringData", "t4");
assertEquals("t4", t4.getStringData()); assertEquals("t4", t4.getStringData());
t4.setTestData(t5); t4.setTestData(t5);
ReflectionUtil.configureClass(t1, "test.testData.testData.testData.testData.stringData", "t5"); ReflectionUtil.configureClass(t1, "testData.testData.testData.testData.stringData", "t5");
assertEquals("t5", t5.getStringData()); assertEquals("t5", t5.getStringData());
} }
public static ReflectionUtilTest valueOf(String data) {
ReflectionUtilTest test = new ReflectionUtilTest();
test.data = data;
return test;
}
public ReflectionUtilTest getTestData() {
return testData;
}
public void setTestData(ReflectionUtilTest testData) {
this.testData = testData;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public class TestClass1 {
private boolean booleanData;
private int intData;
private long longData;
public boolean isBooleanData() { public boolean isBooleanData() {
return booleanData; return booleanData;
} }
@ -124,22 +197,12 @@ public class ReflectionUtilTest extends TestCase {
public void setLongData(long longData) { public void setLongData(long longData) {
this.longData = longData; this.longData = longData;
} }
public short getShortData() {
return shortData;
} }
public void setShortData(short shortData) { public class TestClass2 extends TestClass1 {
this.shortData = shortData; private float floatData;
} private byte byteData;
private char charData;
public double getDoubleData() {
return doubleData;
}
public void setDoubleData(double doubleData) {
this.doubleData = doubleData;
}
public float getFloatData() { public float getFloatData() {
return floatData; return floatData;
@ -164,6 +227,29 @@ public class ReflectionUtilTest extends TestCase {
public void setCharData(char charData) { public void setCharData(char charData) {
this.charData = charData; this.charData = charData;
} }
}
public class TestClass3 extends TestClass2 {
private short shortData;
private double doubleData;
private String stringData;
private TestClass3 testData;
public short getShortData() {
return shortData;
}
public void setShortData(short shortData) {
this.shortData = shortData;
}
public double getDoubleData() {
return doubleData;
}
public void setDoubleData(double doubleData) {
this.doubleData = doubleData;
}
public String getStringData() { public String getStringData() {
return stringData; return stringData;
@ -173,17 +259,12 @@ public class ReflectionUtilTest extends TestCase {
this.stringData = stringData; this.stringData = stringData;
} }
public ReflectionUtilTest getTestData() { public TestClass3 getTestData() {
return testData; return testData;
} }
public void setTestData(ReflectionUtilTest testData) { public void setTestData(TestClass3 testData) {
this.testData = testData; this.testData = testData;
} }
public static ReflectionUtilTest valueOf(String data) {
ReflectionUtilTest obj = new ReflectionUtilTest();
obj.setStringData(data);
return obj;
} }
} }