
You can configure a direct connection to a virtual service from ReadyAPI without using any additional intermediaries.
Add JMS Routes
To add JMS routes to an existing virtual service, right-click the virtual service in the Navigator panel and select JMS Route.
In the subsequent dialog, select the Manual tab and configure JMS endpoint.

Click the image to enlarge it.
JMS Server |
Select one of the JMS servers specified in the JMS dialog or select Create New to create a new JMS server. |
Receive Destination JNDI Name |
The name of the topic or queue that ReadyAPI emulates.
Requests to it will be redirected to the virtual service.
|
Send Destination JNDI Name |
The name of the topic or queue ReadyAPI sends the response to. It can also be configured in the response editor. |
Configure Virtual Service Properties
General JMS Specifics
-
Do not use the same topic (queue) for the request and its response. This may cause an infinite loop: after sending the outgoing message to the topic (or queue), the virtual service will recognize it as an incoming request and will process a reply, and the loop can repeat again and again.
-
Also, remember that in JMS, multiple consumers can subscribe to the same destination. In this case, the destination type – topic or queue – comes into play and specifies how messages are processed:
-
A message that comes to a destination of the topic type can be read by all consumers subscribed to this destination.
-
A message that comes to a queue destination will be read only by one consumer, the other subscribers will not receive it.
When virtualizing JMS services, it is quite easy to create two or more consumers of the same queue destination. This might cause issues during testing, because your test will not receive answers to some messages. The JMS Request test step can run in an infinite waiting loop and you might think that your test has hung (see the example below). Be aware!
Example
Example
Example
Imagine you create a JMS Request test step that sends a message to the Topic1 destination and monitors the Queue1 destination for an answer.
Now imagine that you create a JMS virtual service with two virtual operations:
-
Operation A listens to Topic1 and replies to Queue1, and
-
Operation B listens to Queue1 and replies to Queue2.
So, we have two consumers subscribed to Queue1: the JMS Request test step and Operation B of your virtual service.
Now, if you start your JMS virtual service and run the JMS Request test step, the messages will be processed in the following order:
-
The test step will send a message to the Topic1 destination.
-
The service will receive this message and will reply to Queue1 (according to the Operation A settings).
-
Now the message at Queue1 can be read by Operation B or by the JMS Request test step. Each of them can be faster than the other.
If it is Operation B that captures the message from Queue1, then the test step will not receive the message. It will run in an infinite loop waiting for an answer at Queue1, and you might think your test has hung.
-
You can configure each response individually to use the ReplyTo
value from the incoming request or the destination configured manually. ReadyAPI can send responses to a different queue or a different JMS server. For more information about connection options, see the JMS Response Properties topic.
-
If necessary, you can use the Start script to dynamically configure JMS connection properties. To do this, you call the ConnectionFactoryProducer()
method and provide the required closures. This method should create, configure and return an instance of the ActiveMQConnectionFactory class.The scripts can use the following closures:
contextProducer |
JmsConnectionConfiguration, Properties |
An InitialContext that you use to create the JMS connection. |
connectionFactoryProducer |
InitialContext |
A ConnectionFactory object that you use in your script. |
connectionProducer |
ConnectionFactory |
A JMS Connection object that you use to create the session. |
sessionProducer |
javax.jms.Connection |
A JMS Session object that you use in your script. |
destinationProducer |
javax.jms.Session, String |
A Destination object that specifies the JMS endpoint you send requests to. |
Here is a sample script that creates a connection to Apache ActiveMQ Artemis by using the above closures:
Show Example
Show Example
Hide Example
 |
This example uses libraries of Apache ActiveMQ Artemis. Make sure you have copied the required .jar files to the <ReadyAPI>\bin\ext folder. |
Groovy
// Import Java JMS classes
import javax.jms.*
import com.smartbear.servicev.core.model.impl.jms.*
// Import ActiveMQ classes
import org.apache.activemq.ActiveMQConnectionFactory
import org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient
import org.apache.activemq.artemis.api.jms.JMSFactoryType
import org.apache.activemq.artemis.jms.client.ActiveMQSession
import org.apache.activemq.artemis.jms.client.ActiveMQJMSProducer
import org.apache.activemq.artemis.jms.client.ActiveMQQueue
import org.apache.activemq.artemis.jms.client.ActiveMQMessage
import org.apache.activemq.artemis.jms.client.ActiveMQConnection
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection
import org.apache.activemq.artemis.api.core.*
import org.apache.activemq.artemis.api.core.client.ServerLocator
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory
import org.apache.activemq.artemis.api.core.client.ClientSession
import org.apache.activemq.artemis.core.remoting.impl.netty.*
import org.apache.activemq.artemis.api.core.TransportConfiguration
import org.apache.activemq.artemis.uri.TCPSchema
def mockService = context.mockService
// Set contextProducer to null
mockService.contextProducer = { configuration, additionalProperties ->
return null
}
// Create a connection factory and configure its properties
mockService.connectionFactoryProducer = {
initialContext ->
HashMap<String, Object> map = new HashMap<String, Object>()
map.put(org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants.HOST_PROP_NAME, "127.0.0.1") // Set the JMS provider IP
map.put(org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 61616) // Set the JMS Provider port
TransportConfiguration tcp = new TransportConfiguration(
"org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory",map) // Create a connection that uses the parameters above
ActiveMQConnectionFactory mqFactory = (ActiveMQConnectionFactory) ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, tcp) // Create a connection factory
mqFactory.setClientID("ReadyAPI") // Set the client ID to ReadyAPI
return mqFactory
}
// Create a connection to the destination
mockService.destinationProducer = { initialContext, destinationName ->
return ActiveMQJMSClient.createQueue(destinationName)
}
See Also
JMS Virtual Services
JMS Support
Creating the Connector Plugin