Author: pmouawad
Date: Tue Nov 28 21:06:45 2017
New Revision: 1816573
URL: http://svn.apache.org/viewvc?rev=1816573&view=rev
Log:
Bug 61829 - JMS Point-to-Point : If Receive Queue is empty and a timeout is set, it is not
taken into account
Fixes also timeout == 0 is reset to 2s
Bugzilla Id: 61829
Added:
jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TimeoutEnabledQueueRequestor.java
(with props)
Modified:
jmeter/trunk/bin/testfiles/JMS_TESTS.csv
jmeter/trunk/bin/testfiles/JMS_TESTS.jmx
jmeter/trunk/bin/testfiles/JMS_TESTS.xml
jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/FixedQueueExecutor.java
jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/JMSSampler.java
jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/QueueExecutor.java
jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TemporaryQueueExecutor.java
jmeter/trunk/xdocs/changes.xml
Modified: jmeter/trunk/bin/testfiles/JMS_TESTS.csv
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/testfiles/JMS_TESTS.csv?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/bin/testfiles/JMS_TESTS.csv (original)
+++ jmeter/trunk/bin/testfiles/JMS_TESTS.csv Tue Nov 28 21:06:45 2017
@@ -14,6 +14,7 @@ JMS-P2P-Read,200,1 message(s) received s
JMS-P2P-RequestOnlyForClear,200,OK,TG-JMS-P2P 1-1,text,true,1,1,1,0
JMS-P2P-Clear,200,1 message(s) removed using receive timeout:100ms,TG-JMS-P2P 1-1,text,true,1,1,1,0
JMS-P2P-BrowseAfterClear,200,0 messages available on the queue,TG-JMS-P2P 1-1,text,true,1,1,1,0
+JMS-P2P-Timeout,,No reply message received,TG-JMS-P2P 1-1,text,true,1,1,1,0
JMS Publisher-NonDurable,200,1 messages published,TG-JMS-PS 2-1,,true,1,1,1,0
JMS Subscriber-NonDurable,200,1 message(s) received successfully of 1 expected,TG-JMS-PS
2-1,text,true,1,1,1,0
JMS Publisher-Persistent,200,1 messages published,TG-JMS-PS-Selector-receive 3-1,,true,1,1,1,0
Modified: jmeter/trunk/bin/testfiles/JMS_TESTS.jmx
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/testfiles/JMS_TESTS.jmx?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/bin/testfiles/JMS_TESTS.jmx (original)
+++ jmeter/trunk/bin/testfiles/JMS_TESTS.jmx Tue Nov 28 21:06:45 2017
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<jmeterTestPlan version="1.2" properties="3.4" jmeter="3.4-SNAPSHOT.20171119">
+<jmeterTestPlan version="1.2" properties="3.4" jmeter="4.0-SNAPSHOT.20171128">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
@@ -663,6 +663,37 @@ finally {
<intProp name="Assertion.test_type">16</intProp>
</ResponseAssertion>
<hashTree/>
+ </hashTree>
+ <JMSSampler guiclass="JMSSamplerGui" testclass="JMSSampler" testname="JMS-P2P-Timeout"
enabled="true">
+ <stringProp name="JMSSampler.queueconnectionfactory">ConnectionFactory</stringProp>
+ <stringProp name="JMSSampler.SendQueue">dynamicQueues/requestQueue7</stringProp>
+ <stringProp name="JMSSampler.ReceiveQueue"></stringProp>
+ <intProp name="JMSSampler.communicationStyle">1</intProp>
+ <boolProp name="JMSSampler.isNonPersistent">false</boolProp>
+ <boolProp name="JMSSampler.useReqMsgIdAsCorrelId">true</boolProp>
+ <stringProp name="JMSSampler.timeout">2000</stringProp>
+ <stringProp name="JMSSampler.jmsNumberOfSamplesToAggregate"></stringProp>
+ <stringProp name="HTTPSamper.xml_data">test</stringProp>
+ <stringProp name="JMSSampler.initialContextFactory">org.apache.activemq.jndi.ActiveMQInitialContextFactory</stringProp>
+ <stringProp name="JMSSampler.contextProviderUrl">tcp://localhost:61616</stringProp>
+ <elementProp name="JMSSampler.jndiProperties" elementType="Arguments" guiclass="ArgumentsPanel"
testclass="Arguments" testname="User Defined Variables" enabled="true">
+ <collectionProp name="Arguments.arguments"/>
+ </elementProp>
+ <elementProp name="arguments" elementType="JMSProperties">
+ <collectionProp name="JMSProperties.properties"/>
+ </elementProp>
+ <boolProp name="JMSSampler.useResMsgIdAsCorrelId">true</boolProp>
+ </JMSSampler>
+ <hashTree>
+ <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="RA_noMessage"
enabled="true">
+ <collectionProp name="Asserion.test_strings">
+ <stringProp name="1882001775">No reply message received</stringProp>
+ </collectionProp>
+ <stringProp name="Assertion.test_field">Assertion.response_message</stringProp>
+ <boolProp name="Assertion.assume_success">true</boolProp>
+ <intProp name="Assertion.test_type">16</intProp>
+ </ResponseAssertion>
+ <hashTree/>
</hashTree>
</hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="TG-JMS-PS"
enabled="true">
Modified: jmeter/trunk/bin/testfiles/JMS_TESTS.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/testfiles/JMS_TESTS.xml?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/bin/testfiles/JMS_TESTS.xml (original)
+++ jmeter/trunk/bin/testfiles/JMS_TESTS.xml Tue Nov 28 21:06:45 2017
@@ -99,6 +99,13 @@
<error>false</error>
</assertionResult>
</sample>
+<sample s="true" lb="JMS-P2P-Timeout" rc="" rm="No reply message received" tn="TG-JMS-P2P
1-1" dt="text" sc="1" ec="0" ng="1" na="1">
+ <assertionResult>
+ <name>RA_noMessage</name>
+ <failure>false</failure>
+ <error>false</error>
+ </assertionResult>
+</sample>
<sample s="true" lb="JMS Publisher-NonDurable" rc="200" rm="1 messages published" tn="TG-JMS-PS
2-1" dt="" sc="1" ec="0" ng="1" na="1">
<assertionResult>
<name>Response Assertion</name>
Modified: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/FixedQueueExecutor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/FixedQueueExecutor.java?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/FixedQueueExecutor.java
(original)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/FixedQueueExecutor.java
Tue Nov 28 21:06:45 2017
@@ -95,10 +95,11 @@ public class FixedQueueExecutor implemen
// This used to be request.wait(timeout_ms), where 0 means forever
// However 0 means return immediately for the latch
if (timeout == 0){
+ log.debug("Waiting infinitely for message");
countDownLatch.await(); //
} else {
if(!countDownLatch.await(timeout, TimeUnit.MILLISECONDS)) {
- log.debug("Timeout reached before getting a reply message");
+ log.debug("Timeout {} ms reached before getting a reply message", timeout);
}
}
log.debug("{} done waiting for {} on {} ended on {}",
@@ -110,4 +111,9 @@ public class FixedQueueExecutor implemen
}
return admin.get(id);
}
+
+ @Override
+ public void close() throws JMSException {
+ // NOOP
+ }
}
Modified: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/JMSSampler.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/JMSSampler.java?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/JMSSampler.java (original)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/JMSSampler.java Tue
Nov 28 21:06:45 2017
@@ -43,6 +43,7 @@ import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
+import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.jms.Utils;
import org.apache.jmeter.samplers.AbstractSampler;
@@ -678,7 +679,7 @@ public class JMSSampler extends Abstract
producer.setTimeToLive(Long.parseLong(getExpiration()));
} else {
if (useTemporyQueue()) {
- executor = new TemporaryQueueExecutor(session, sendQueue);
+ executor = new TemporaryQueueExecutor(session, sendQueue, getTimeoutAsInt());
} else {
producer = session.createSender(sendQueue);
executor = new FixedQueueExecutor(producer, getTimeoutAsInt(), isUseReqMsgIdAsCorrelId());
@@ -755,10 +756,12 @@ public class JMSSampler extends Abstract
}
private int getTimeoutAsInt() {
- if (getPropertyAsInt(TIMEOUT) < 1) {
+ String propAsString = getPropertyAsString(TIMEOUT);
+ if(StringUtils.isEmpty(propAsString)){
return DEFAULT_TIMEOUT;
+ } else {
+ return Integer.parseInt(propAsString);
}
- return getPropertyAsInt(TIMEOUT);
}
public String getTimeout() {
@@ -797,6 +800,13 @@ public class JMSSampler extends Abstract
// ignore
}
}
+ if (executor != null) {
+ try {
+ executor.close();
+ } catch (JMSException e) {
+ LOGGER.error("Error closing executor {}", executor.getClass(), e);
+ }
+ }
Utils.close(session, LOGGER);
Utils.close(connection, LOGGER);
if (receiverThread != null) {
Modified: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/QueueExecutor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/QueueExecutor.java?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/QueueExecutor.java
(original)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/QueueExecutor.java
Tue Nov 28 21:06:45 2017
@@ -18,12 +18,13 @@
package org.apache.jmeter.protocol.jms.sampler;
+import java.io.Closeable;
+
import javax.jms.JMSException;
import javax.jms.Message;
/**
* Executor for (pseudo) synchronous communication. <br>
- * Created on: October 28, 2004
*
*/
public interface QueueExecutor {
@@ -43,4 +44,9 @@ public interface QueueExecutor {
int priority,
long expiration) throws JMSException;
+ /**
+ * Close the resources
+ * @throws JMSException
+ */
+ void close() throws JMSException;
}
Modified: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TemporaryQueueExecutor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TemporaryQueueExecutor.java?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TemporaryQueueExecutor.java
(original)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TemporaryQueueExecutor.java
Tue Nov 28 21:06:45 2017
@@ -24,14 +24,19 @@ import javax.jms.Queue;
import javax.jms.QueueRequestor;
import javax.jms.QueueSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Request/reply executor with a temporary reply queue. <br>
*
* Used by JMS Sampler (Point to Point)
*/
public class TemporaryQueueExecutor implements QueueExecutor {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TemporaryQueueExecutor.class);
/** The sender and receiver. */
- private final QueueRequestor requestor;
+ private final TimeoutEnabledQueueRequestor requestor;
+ private int timeout;
/**
* Constructor.
@@ -40,13 +45,15 @@ public class TemporaryQueueExecutor impl
* the session to use to send the message
* @param destination
* the queue to send the message on
+ * @param timeoutMs Timeout in millis
* @throws JMSException
* when internally used {@link QueueRequestor} can not be
* constructed with <code>session</code> and
* <code>destination</code>
*/
- public TemporaryQueueExecutor(QueueSession session, Queue destination) throws JMSException
{
- requestor = new QueueRequestor(session, destination);
+ public TemporaryQueueExecutor(QueueSession session, Queue destination, int timeoutMs)
throws JMSException {
+ requestor = new TimeoutEnabledQueueRequestor(session, destination);
+ this.timeout = timeoutMs;
}
/**
@@ -57,6 +64,13 @@ public class TemporaryQueueExecutor impl
int deliveryMode,
int priority,
long expiration) throws JMSException {
- return requestor.request(request);
+ LOGGER.debug("Sending message and waiting for response in Temporary queue with timeout
{} ms (0==infinite)",
+ timeout);
+ return requestor.request(request, timeout);
+ }
+
+ @Override
+ public void close() throws JMSException {
+ requestor.close();
}
}
Added: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TimeoutEnabledQueueRequestor.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TimeoutEnabledQueueRequestor.java?rev=1816573&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TimeoutEnabledQueueRequestor.java
(added)
+++ jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TimeoutEnabledQueueRequestor.java
Tue Nov 28 21:06:45 2017
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.jmeter.protocol.jms.sampler;
+
+import javax.jms.InvalidDestinationException;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TemporaryQueue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>TimeoutEnabledQueueRequestor</code> helper class simplifies making
+ * service requests using the request/reply pattern.
+ *
+ * <P>
+ * The <code>TimeoutEnabledQueueRequestor</code> constructor is given a
+ * non-transacted <code>QueueSession</code> and a destination
+ * <code>Queue</code>. It creates a <code>TemporaryQueue</code> for
the
+ * responses and provides a <code>request</code> method that sends the request
+ * message and waits for its reply.
+ *
+ * @since 4.0
+ */
+public class TimeoutEnabledQueueRequestor {
+ private static final Logger logger = LoggerFactory.getLogger(TimeoutEnabledQueueRequestor.class);
+ private Session session; // The queue session to which the queue belongs.
+ private TemporaryQueue tempQueue;
+ private MessageProducer sender;
+ private MessageConsumer receiver;
+
+ /**
+ * Constructor for the <code>TimeoutEnabledQueueRequestor</code> class.
+ *
+ * <P>
+ * This implementation assumes the session parameter to be non-transacted,
+ * with a delivery mode of either <code>AUTO_ACKNOWLEDGE</code> or
+ * <code>DUPS_OK_ACKNOWLEDGE</code>.
+ *
+ * @paramsession the <code>QueueSession</code> the queue belongs to
+ * @paramqueue the queue to performthe request/reply call on
+ *
+ * @exception JMSException
+ * if the JMS provider fails to create the
+ * <code>TimeoutEnabledQueueRequestor</code> due to some
+ * internal error.
+ * @exception InvalidDestinationException
+ * if an invalid queue is specified.
+ */
+ public TimeoutEnabledQueueRequestor(Session session, Queue queue) throws JMSException
{
+ this.session = session;
+ tempQueue = session.createTemporaryQueue();
+ sender = session.createProducer(queue);
+ receiver = session.createConsumer(tempQueue);
+ }
+
+ /**
+ * Sends a request and waits for a reply. The temporary queue is used for
+ * the <code>JMSReplyTo</code> destination, and only one reply per request
+ * is expected. The method blocks indefinitely until a message arrives!
+ *
+ * @parammessage the message to send
+ *
+ * @return the reply message
+ *
+ * @exception JMSException
+ * if the JMS provider fails to complete the request due to
+ * some internal error.
+ */
+ public Message request(Message message) throws JMSException {
+ return request(message, 0);
+ }
+
+ /**
+ * Sends a request and waits for a reply. The temporary queue is used for
+ * the <code>JMSReplyTo</code> destination, and only one reply per request
+ * is expected. The client waits/blocks for the reply until the timeout is
+ * reached.
+ *
+ * @param message
+ * the message to send
+ * @param timeout
+ * time to wait for a reply on temporary queue. If you specify no
+ * arguments or an argument of 0, the method blocks indefinitely
+ * until a message arrives
+ *
+ * @return the reply message
+ *
+ * @exception JMSException
+ * if the JMS provider fails to complete the request due to
+ * some internal error.
+ */
+ public Message request(Message message, long timeout) throws JMSException {
+ message.setJMSReplyTo(tempQueue);
+ sender.send(message);
+ return receiver.receive(timeout);
+ }
+
+ /**
+ * Closes the <code>TimeoutEnabledQueueRequestor</code> and its session.
+ *
+ * <P>
+ * Since a provider may allocate some resources on behalf of a
+ * <code>TimeoutEnabledQueueRequestor</code> outside the Java virtual
+ * machine, clients should close them when they are not needed. Relying on
+ * garbage collection to eventually reclaim these resources may not be
+ * timely enough.
+ *
+ * <P>
+ * This method closes the <code>Session</code> object passed to the
+ * <code>TimeoutEnabledQueueRequestor</code> constructor.
+ *
+ * @exception JMSException
+ * if the JMS provider fails to close the
+ * <code>TimeoutEnabledQueueRequestor</code> due to some
+ * internal error.
+ */
+ public void close() throws JMSException {
+ String queueName = tempQueue.getQueueName();
+ try {
+ tempQueue.delete();
+ } catch (Exception e) {
+ logger.error("Error deleting tempQueue {}", queueName);
+ }
+ // publisher and consumer created by constructor are implicitly closed.
+ try {
+ session.close();
+ } catch (Exception e) {
+ logger.error("Error closing session", e);
+ }
+ }
+}
Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TimeoutEnabledQueueRequestor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/protocol/jms/org/apache/jmeter/protocol/jms/sampler/TimeoutEnabledQueueRequestor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1816573&r1=1816572&r2=1816573&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Tue Nov 28 21:06:45 2017
@@ -85,6 +85,7 @@ Summary
JMeter will move the <code>Mirror Server</code>, <code>Property Display</code>
and HTTP(s) <code>Test Script Recorder</code> elements as direct children of Test
Plan. For
any other element, it will create a <code>Test Fragment</code> element called
<code>Workbench Test Fragment and move the elements in it</code>.</li>
<li>Following classes have been dropped (<code>org.apache.jmeter.functions.util.ArgumentEncoder</code>,
<code>org.apache.jmeter.functions.util.ArgumentDecoder</code>), see <pr>335</pr></li>
+ <li>In JMS Point-to-Point sampler, setting timeout to 0 will now mean infinite
timeout while previously it would be switched to 2000 ms, see <bugzilla>61829</bugzilla></li>
</ul>
<!-- =================== Improvements =================== -->
@@ -104,6 +105,7 @@ Summary
<li><bug>61739</bug>Java Request / JavaSamplerClient : Improve <code>org.apache.jmeter.protocol.java.sampler.JavaSamplerContext</code></li>
<li><bug>61762</bug>Start Next Thread Loop should be used everywhere</li>
<li><bug>61544</bug>JMS Point-to-Point Sampler: Enhance communication
styles with read, browse, clear. Based on a contribution by Benny van Wijngaarden (benny at
smaragd-it.nl)</li>
+ <li><bug>61829</bug>JMS Point-to-Point : If Receive Queue is empty
and a timeout is set, it is not taken into account. Contributed by Ubik Load Pack (support
at ubikloadpack.com)</li>
</ul>
<h3>Controllers</h3>
|