From 396095194178c8b1ec6da7581314c8625139c428 Mon Sep 17 00:00:00 2001 From: oulaly Date: Sun, 18 Apr 2021 18:32:05 +0800 Subject: [PATCH] support gui custom queue declare arguments like 'x-' prefix, from https://github.com/voytek-solutions/JMeter-Rabbit-AMQP and fix value type issue --- .../jmeter/protocol/amqp/AMQPSampler.java | 57 +++++++++++++++++-- .../protocol/amqp/gui/AMQPPublisherGui.java | 2 +- .../protocol/amqp/gui/AMQPSamplerGui.java | 26 +++++++++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/src/main/com/zeroclue/jmeter/protocol/amqp/AMQPSampler.java b/src/main/com/zeroclue/jmeter/protocol/amqp/AMQPSampler.java index 7fee5fd..b849ff3 100644 --- a/src/main/com/zeroclue/jmeter/protocol/amqp/AMQPSampler.java +++ b/src/main/com/zeroclue/jmeter/protocol/amqp/AMQPSampler.java @@ -2,7 +2,11 @@ import com.rabbitmq.client.*; import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.config.Argument; +import org.apache.jmeter.config.Arguments; import org.apache.jmeter.samplers.AbstractSampler; +import org.apache.jmeter.testelement.property.PropertyIterator; +import org.apache.jmeter.testelement.property.TestElementProperty; import org.apache.jmeter.testelement.ThreadListener; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; @@ -10,10 +14,9 @@ import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.*; public abstract class AMQPSampler extends AbstractSampler implements ThreadListener { @@ -57,6 +60,7 @@ public abstract class AMQPSampler extends AbstractSampler implements ThreadListe private static final String QUEUE_EXCLUSIVE = "AMQPSampler.QueueExclusive"; private static final String QUEUE_AUTO_DELETE = "AMQPSampler.QueueAutoDelete"; private static final int DEFAULT_HEARTBEAT = 1; + private static final String CHANNEL_ARGUMENTS = "AMQPPublisher.ChannelArguments"; private transient ConnectionFactory factory; private transient Connection connection; @@ -122,9 +126,46 @@ private Map getQueueArguments() { if(getMessageExpires() != null && !getMessageExpires().isEmpty()) arguments.put("x-expires", getMessageExpiresAsInt()); + // You can explicitly set x-expires, x-message-ttl and other arguments. + // Use getChannelArguments().getArgumentsAsMap() to get String value; use argumentsAsMap(getChannelArguments()) to get Object value (Number, Boolean, String). + arguments.putAll(argumentsAsMap(getChannelArguments())); + return arguments; } + private Map argumentsAsMap(Arguments args) { + PropertyIterator iter = args.getArguments().iterator(); + Map argMap = new LinkedHashMap(); + while (iter.hasNext()) { + Argument arg = (Argument) iter.next().getObjectValue(); + if (!argMap.containsKey(arg.getName())) { + String value = arg.getValue(); + Number numVal = argumentValueAsNumber(value); + Boolean boolVal = argumentValueAsBoolean(value); + argMap.put(arg.getName(), numVal != null ? numVal : (boolVal != null ? boolVal : value)); + } + } + return argMap; + } + + private Number argumentValueAsNumber(String value) { + if (value == null) { + return null; + } + try { + return NumberFormat.getInstance().parse(value); + } catch (ParseException e) { + return null; + } + } + + private Boolean argumentValueAsBoolean(String value) { + if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) { + return Boolean.valueOf(value); + } + return null; + } + protected abstract Channel getChannel(); protected abstract void setChannel(Channel channel); @@ -384,6 +425,14 @@ public void setQueueRedeclare(Boolean content) { setProperty(QUEUE_REDECLARE, content); } + public Arguments getChannelArguments() { + return (Arguments) getProperty(CHANNEL_ARGUMENTS).getObjectValue(); + } + + public void setChannelArguments(Arguments channelArguments) { + setProperty(new TestElementProperty(CHANNEL_ARGUMENTS, channelArguments)); + } + protected void cleanup() { try { //getChannel().close(); // closing the connection will close the channel if it's still open diff --git a/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPPublisherGui.java b/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPPublisherGui.java index bde4d00..257951f 100644 --- a/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPPublisherGui.java +++ b/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPPublisherGui.java @@ -179,4 +179,4 @@ private void configureHeaders(AMQPPublisher sampler) headers.clearGui(); } } -} \ No newline at end of file +} diff --git a/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPSamplerGui.java b/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPSamplerGui.java index d5de0eb..0d4f59f 100644 --- a/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPSamplerGui.java +++ b/src/main/com/zeroclue/jmeter/protocol/amqp/gui/AMQPSamplerGui.java @@ -1,6 +1,8 @@ package com.zeroclue.jmeter.protocol.amqp.gui; import com.zeroclue.jmeter.protocol.amqp.AMQPSampler; +import org.apache.jmeter.config.Arguments; +import org.apache.jmeter.config.gui.ArgumentsPanel; import org.apache.jmeter.gui.util.VerticalPanel; import org.apache.jmeter.samplers.gui.AbstractSamplerGui; import org.apache.jmeter.testelement.TestElement; @@ -42,6 +44,10 @@ public abstract class AMQPSamplerGui extends AbstractSamplerGui { private final JLabeledTextField iterations = new JLabeledTextField("Number of samples to Aggregate"); + /** + * AMQP Channel Arguments Panel (Auto parsed 'Value' type: 'Number', 'Boolean', 'String') + */ + private ArgumentsPanel channelArguments = new ArgumentsPanel("Channel Arguments"); protected abstract void setMainPanel(JPanel panel); @@ -52,7 +58,9 @@ public abstract class AMQPSamplerGui extends AbstractSamplerGui { @Override public void configure(TestElement element) { super.configure(element); + if (!(element instanceof AMQPSampler)) return; + AMQPSampler sampler = (AMQPSampler) element; exchange.setText(sampler.getExchange()); @@ -78,9 +86,22 @@ public void configure(TestElement element) { username.setText(sampler.getUsername()); password.setText(sampler.getPassword()); SSL.setSelected(sampler.connectionSSL()); + + configureChannelArguments(sampler); + log.info("AMQPSamplerGui.configure() called"); } + private void configureChannelArguments(AMQPSampler sampler) + { + Arguments sampleChannelArguments = sampler.getChannelArguments(); + if (sampleChannelArguments != null) { + channelArguments.configure(sampleChannelArguments); + } else { + channelArguments.clearGui(); + } + } + /** * {@inheritDoc} */ @@ -110,6 +131,8 @@ public void clearGui() { username.setText("guest"); password.setText("guest"); SSL.setSelected(false); + + channelArguments.clearGui(); } /** @@ -145,6 +168,8 @@ public void modifyTestElement(TestElement element) { sampler.setPassword(password.getText()); sampler.setConnectionSSL(SSL.isSelected()); log.info("AMQPSamplerGui.modifyTestElement() called, set user/pass to " + username.getText() + "/" + password.getText() + " on sampler " + sampler); + + sampler.setChannelArguments((Arguments) channelArguments.createTestElement()); } protected void init() { @@ -244,6 +269,7 @@ private Component makeCommonPanel() { JPanel exchangeQueueSettings = new VerticalPanel(); exchangeQueueSettings.add(exchangeSettings); exchangeQueueSettings.add(queueSettings); + exchangeQueueSettings.add(channelArguments); commonPanel.add(exchangeQueueSettings, gridBagConstraintsCommon);