You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by drystone <dr...@mailinator.com> on 2006/06/05 18:05:56 UTC

Using ActiveMQ embedded sever for Testing

Hi,
I am sorry if this is a question that has been asked before but I could not
find anything that could help me after a lengthly search.

I would like to use ActiveMQ embedded server as a server for integration
testing of my JMS code. Please can somebody give me a description of how I
would set this up.  I expect that I would need to create a BrokerService
using the url vm://localhost:port.  I am not sure what the BrokerService
will give me except that it will listen on that port.  How do I set up a
queue in code for the BrokerService to support.  I do not want to use a
property file or xml config file. The properties will be loaded using a
different mechanism.

Once this is setup do I just use the normal JMS mechanisms to put and get
things from the queue.

Any response will be greatly appriciated.
Thanks for your Help. 
D
--
View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4717413
Sent from the ActiveMQ - User forum at Nabble.com.


Re: Using ActiveMQ embedded sever for Testing

Posted by James Strachan <ja...@gmail.com>.
If you want to run your same code on lots of different JMS providers
then sure using JNDI is one way to solve this. Another is to use a
Spring XML config file to abstract away how you get the
ConnectionFactory.

Typically folks seem to have lots of problems using JNDI - which is
why I was recommending you use 1 line of Java code which just works
and solves your problem. You were writing in Java code the code to
create a JNDI context anyway - so really you were already using
ActiveMQ specific Java code to make your ConnectionFactory - which is
why I suggested the one liner that will just work.

But by all means keep on trucking with JNDI - but if you really want
your Java code to not have any runtime dependency on any specific JMS
provider then I'd recommend using a jndi.properties file on the
classpath then just constructing the InitialContext.

There's an example here:
http://incubator.apache.org/activemq/jndi-support.html


On 6/6/06, drystone <dr...@mailinator.com> wrote:
>
> Maybe I am going about this in the wrong manner but the code that I am trying
> to test is vendor neutral  JMS code.  I am trying to test code that will
> send and receive messages for different implementations of the JMS spec:
>
> Example of code that I am trying to test:
>
> Properties properties = could equal JBoss/MQSeries/ActiveMQ properties
> InitialContext initialContext = new InitialContext( properties );
> Queue queue = (Queue) initialContext.lookup( queueName );
> QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)
>            initialContext.lookup( JBoss/MQSeries/ActiveMQ ConnectionFactory
> );
> QueueConnection queueConnection =
> queueConnectionFactory.createQueueConnection();
> QueueSession queueSession = queueConnection.createQueueSession( false,
>            Session.AUTO_ACKNOWLEDGE );
> QueueSender queueSender = queueSession.createSender( queue )
> Message jmsMessage = queueSession.createTextMessage( message.toString() );
> queueSender.send( message );
> ...
> similar for receiving JMS messages
> ....
>
> I do not want to add any ActiveMQ specific code for the above. I was hoping
> that I would be able to build a configuration object, one for each of the
> JMS implementations JBoss/MQSeries/ActiveMQ. These objects would be used
> within the generic JMS code to set the correct values in the JMS objects and
> they would use the configured resources present.  The generic JMS code that
> I have works for both JBoss and QSeries, I would just like a way of testing
> it. I thought that if there was this BrokerService present that would get
> picked up and would be used.
>
> If I used ConnectionFactory connectionFactory = new
> ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");  this
> would be a different way that I would be accessing a JMS resource instead of
> the generic code above, and by passing the code that my application uses
> therefore not fully testing it.
>
> I am sorry if I am being stupid but I am new to ActiveMQ and do not fully
> understand how it should work. Should I be swapping out my generic JMS code
> for ActiveMQ code when I am testing application sections that use JMS?
>
> Thanks for your help.
> D
> --
> View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4735410
> Sent from the ActiveMQ - User forum at Nabble.com.
>
>


-- 

James
-------
http://radio.weblogs.com/0112098/

Re: Using ActiveMQ embedded sever for Testing

Posted by drystone <dr...@mailinator.com>.
Maybe I am going about this in the wrong manner but the code that I am trying
to test is vendor neutral  JMS code.  I am trying to test code that will
send and receive messages for different implementations of the JMS spec:

Example of code that I am trying to test:

Properties properties = could equal JBoss/MQSeries/ActiveMQ properties
InitialContext initialContext = new InitialContext( properties );
Queue queue = (Queue) initialContext.lookup( queueName );
QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)
           initialContext.lookup( JBoss/MQSeries/ActiveMQ ConnectionFactory
);
QueueConnection queueConnection =
queueConnectionFactory.createQueueConnection();
QueueSession queueSession = queueConnection.createQueueSession( false,
           Session.AUTO_ACKNOWLEDGE );
QueueSender queueSender = queueSession.createSender( queue )
Message jmsMessage = queueSession.createTextMessage( message.toString() );
queueSender.send( message );
...
similar for receiving JMS messages
....

I do not want to add any ActiveMQ specific code for the above. I was hoping
that I would be able to build a configuration object, one for each of the
JMS implementations JBoss/MQSeries/ActiveMQ. These objects would be used
within the generic JMS code to set the correct values in the JMS objects and
they would use the configured resources present.  The generic JMS code that
I have works for both JBoss and QSeries, I would just like a way of testing
it. I thought that if there was this BrokerService present that would get
picked up and would be used.

If I used ConnectionFactory connectionFactory = new
ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");  this
would be a different way that I would be accessing a JMS resource instead of
the generic code above, and by passing the code that my application uses
therefore not fully testing it.

I am sorry if I am being stupid but I am new to ActiveMQ and do not fully
understand how it should work. Should I be swapping out my generic JMS code
for ActiveMQ code when I am testing application sections that use JMS?

Thanks for your help.
D
--
View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4735410
Sent from the ActiveMQ - User forum at Nabble.com.


Re: Using ActiveMQ embedded sever for Testing

Posted by James Strachan <ja...@gmail.com>.
Rather than all this code and these abstractions - why not just
replace it with the one line of code mentioned in the FAQ entry
(http://incubator.apache.org/activemq/how-to-unit-test-jms-code.html)-
then there's no complexity of JNDI etc?

ConnectionFactory connectionFactory = new
ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");

If you need to use a destination just create it

Destination foo = new ActiveMQQueue("foo.bar");

then your testing code is nice and simple.

On 6/6/06, drystone <dr...@mailinator.com> wrote:
>
>
> Thanks for the help but I am still struggling to get it to work. I have
> create an object to act as my broker service:
>
> public class ActiveMqEmbeddedServer {
>     public static final String DEFAULT_CONNECTOR_URI =
> "vm://localhost:8686";
>     private BrokerService brokerService = null;
>     public ActiveMqEmbeddedServer( String connectorUri ) {
>         brokerService = new BrokerService();
>         brokerService.setPersistent( false );
>         brokerService.addConnector( connectorUri );
>         brokerService.start();
>     }
>     public void addQueue( String queueName ) {
>         // Not sure want I am doing here
>         String fullQueueName = ActiveMQDestination.QUEUE_QUALIFIED_PREFIX +
> queueName;
>         ActiveMQDestination destination =
> ActiveMQDestination.createDestination( fullQueueName,
>                   ActiveMQDestination.QUEUE_TYPE );
>         PolicyEntry policyEntry = new PolicyEntry();
>         //policyEntry.configure( new Queue( destination, null, null, null,
> null ) );
>         policyEntry.setDestination( destination );
>         List<PolicyEntry> policyEntries = new ArrayList<PolicyEntry>();
>         policyEntries.add( policyEntry );
>         PolicyMap policyMap = new PolicyMap();
>         policyMap.setPolicyEntries( policyEntries );
>         brokerService.setDestinationPolicy( policyMap );
>     }
> }
>
> I was hoping that this would act as my jms server. I have a JMS sender
> object that does
>
> Properties properties = new Properties();
> properties.put( Context.INITIAL_CONTEXT_FACTORY,
>           "org.apache.activemq.jndi.ActiveMQInitialContextFactory" );
> properties.put( Context.PROVIDER_URL, "vm://localhost:8686");
> InitialContext initialContext = new InitialContext( properties );
> Queue queue = (Queue) initialContext.lookup( "TestQueue" );
> QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)
> initialContext.lookup(
>           "ConnectionFactory" );
> QueueConnection queueConnection =
> queueConnectionFactory.createQueueConnection();
> QueueSession queueSession = queueConnection.createQueueSession( false,
>           Session.AUTO_ACKNOWLEDGE );
> QueueSender queueSender = queueSession.createSender( queue )
> Message jmsMessage = queueSession.createTextMessage( message.toString() );
> queueSender.send( message );
> queueConnection.start();
> queueSender.close();
> queueConnection.stop();
>
> My test looks like this:
>
> public class JmsSendingAndReceivingTest extends TestCase {
>     private static final String TEST_MESSAGE = "This is a test message";
>     private static final String TEST_QUEUE_NAME = "TestQueue";
>     private ActiveMqEmbeddedServer embeddedServer = null;
>     private ActiveMqConfiguration configuration = null;
>     protected void setUp() throws Exception {
>         super.setUp();
>         configuration = new ActiveMqConfiguration( "localhost", "8686",
> "TestQueue",
>                  ActiveMqConfiguration.Protocol.VM, null );
>         embeddedServer = new ActiveMqEmbeddedServer(
> configuration.getProvidorUrl()  );
>         embeddedServer.addQueue( TEST_QUEUE_NAME );
>     }
>     public void testSendAndRecieve() throws JmsException {
>         JmsSender jmsSender = new JmsSender( configuration );
>         jmsSender.sendMessage( TEST_MESSAGE );
>     }
>     protected void tearDown() throws Exception {
>         super.tearDown();
>         embeddedServer.stopService();
>     }
> }
>
> I was hoping that I would be able to add queues and topics to the broker
> server and use them through the normal JMS manner.  Please can you point me
> in the right direction.
> Thanks for your help,
> D
> --
> View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4733351
> Sent from the ActiveMQ - User forum at Nabble.com.
>
>


-- 

James
-------
http://radio.weblogs.com/0112098/

Re: Using ActiveMQ embedded sever for Testing

Posted by drystone <dr...@mailinator.com>.
I also noticed this commented out code:

public class ActiveMQInitialContextFactory implements InitialContextFactory
{
   public Context getInitialContext(Hashtable environment) throws
NamingException {
        // lets create a factory
        Map data = new ConcurrentHashMap();
        String[] names = getConnectionFactoryNames(environment);
        for (int i = 0; i < names.length; i++) {
            ActiveMQConnectionFactory factory =null;
            String name = names[i];
            try{
             factory = createConnectionFactory(name, environment);
            }catch(Exception e){
                throw new NamingException("Invalid broker URL");

            }
       /*     if( broker==null ) {
                try {
                    broker = factory.getEmbeddedBroker();
                }
                catch (JMSException e) {
                    log.warn("Failed to get embedded broker", e);
                }
            }
       */
            data.put(name,factory);
        }

        createQueues(data, environment);
        createTopics(data, environment);
        /*
        if (broker != null) {
            data.put("destinations",
broker.getDestinationContext(environment));
        }
        */

...

Would that effect the broker from working?
--
View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4733464
Sent from the ActiveMQ - User forum at Nabble.com.


Re: Using ActiveMQ embedded sever for Testing

Posted by drystone <dr...@mailinator.com>.
I also noticed this commented out code:

public class ActiveMQInitialContextFactory implements InitialContextFactory
{
   public Context getInitialContext(Hashtable environment) throws
NamingException {
        // lets create a factory
        Map data = new ConcurrentHashMap();
        String[] names = getConnectionFactoryNames(environment);
        for (int i = 0; i < names.length; i++) {
            ActiveMQConnectionFactory factory =null;
            String name = names[i];
            try{
             factory = createConnectionFactory(name, environment);
            }catch(Exception e){
                throw new NamingException("Invalid broker URL");

            }
       /*     if( broker==null ) {
                try {
                    broker = factory.getEmbeddedBroker();
                }
                catch (JMSException e) {
                    log.warn("Failed to get embedded broker", e);
                }
            }
       */
            data.put(name,factory);
        }

        createQueues(data, environment);
        createTopics(data, environment);
        /*
        if (broker != null) {
            data.put("destinations",
broker.getDestinationContext(environment));
        }
        */

...

Would that effect the broker from work?
--
View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4733464
Sent from the ActiveMQ - User forum at Nabble.com.


Re: Using ActiveMQ embedded sever for Testing

Posted by drystone <dr...@mailinator.com>.

Thanks for the help but I am still struggling to get it to work. I have
create an object to act as my broker service:

public class ActiveMqEmbeddedServer {
    public static final String DEFAULT_CONNECTOR_URI =
"vm://localhost:8686";
    private BrokerService brokerService = null;
    public ActiveMqEmbeddedServer( String connectorUri ) {
        brokerService = new BrokerService();
        brokerService.setPersistent( false );
        brokerService.addConnector( connectorUri );
        brokerService.start();
    }
    public void addQueue( String queueName ) {
        // Not sure want I am doing here
        String fullQueueName = ActiveMQDestination.QUEUE_QUALIFIED_PREFIX +
queueName;
        ActiveMQDestination destination =
ActiveMQDestination.createDestination( fullQueueName,       
                  ActiveMQDestination.QUEUE_TYPE );
        PolicyEntry policyEntry = new PolicyEntry();
        //policyEntry.configure( new Queue( destination, null, null, null,
null ) );
        policyEntry.setDestination( destination );
        List<PolicyEntry> policyEntries = new ArrayList<PolicyEntry>();
        policyEntries.add( policyEntry );
        PolicyMap policyMap = new PolicyMap();
        policyMap.setPolicyEntries( policyEntries );
        brokerService.setDestinationPolicy( policyMap );
    }
}

I was hoping that this would act as my jms server. I have a JMS sender
object that does

Properties properties = new Properties();
properties.put( Context.INITIAL_CONTEXT_FACTORY,   
          "org.apache.activemq.jndi.ActiveMQInitialContextFactory" );
properties.put( Context.PROVIDER_URL, "vm://localhost:8686");
InitialContext initialContext = new InitialContext( properties );
Queue queue = (Queue) initialContext.lookup( "TestQueue" );
QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory)
initialContext.lookup(   
          "ConnectionFactory" );
QueueConnection queueConnection =
queueConnectionFactory.createQueueConnection();
QueueSession queueSession = queueConnection.createQueueSession( false,   
          Session.AUTO_ACKNOWLEDGE );
QueueSender queueSender = queueSession.createSender( queue )
Message jmsMessage = queueSession.createTextMessage( message.toString() );
queueSender.send( message );
queueConnection.start();
queueSender.close();
queueConnection.stop();

My test looks like this:

public class JmsSendingAndReceivingTest extends TestCase {
    private static final String TEST_MESSAGE = "This is a test message";
    private static final String TEST_QUEUE_NAME = "TestQueue";
    private ActiveMqEmbeddedServer embeddedServer = null;
    private ActiveMqConfiguration configuration = null;
    protected void setUp() throws Exception {
        super.setUp();
        configuration = new ActiveMqConfiguration( "localhost", "8686",
"TestQueue",        
                 ActiveMqConfiguration.Protocol.VM, null );
        embeddedServer = new ActiveMqEmbeddedServer(
configuration.getProvidorUrl()  );
        embeddedServer.addQueue( TEST_QUEUE_NAME );
    }
    public void testSendAndRecieve() throws JmsException {       
        JmsSender jmsSender = new JmsSender( configuration );
        jmsSender.sendMessage( TEST_MESSAGE );
    }
    protected void tearDown() throws Exception {
        super.tearDown();
        embeddedServer.stopService();
    }
}

I was hoping that I would be able to add queues and topics to the broker
server and use them through the normal JMS manner.  Please can you point me
in the right direction.
Thanks for your help,
D
--
View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4733351
Sent from the ActiveMQ - User forum at Nabble.com.


Re: Using ActiveMQ embedded sever for Testing

Posted by James Strachan <ja...@gmail.com>.
I've just added an entry to the FAQ on unit testing JMS code

http://activemq.org/site/how-to-unit-test-jms-code.html

On 6/5/06, drystone <dr...@mailinator.com> wrote:
>
> Hi,
> I am sorry if this is a question that has been asked before but I could not
> find anything that could help me after a lengthly search.
>
> I would like to use ActiveMQ embedded server as a server for integration
> testing of my JMS code. Please can somebody give me a description of how I
> would set this up.  I expect that I would need to create a BrokerService
> using the url vm://localhost:port.  I am not sure what the BrokerService
> will give me except that it will listen on that port.  How do I set up a
> queue in code for the BrokerService to support.  I do not want to use a
> property file or xml config file. The properties will be loaded using a
> different mechanism.
>
> Once this is setup do I just use the normal JMS mechanisms to put and get
> things from the queue.
>
> Any response will be greatly appriciated.
> Thanks for your Help.
> D
> --
> View this message in context: http://www.nabble.com/Using-ActiveMQ-embedded-sever-for-Testing-t1736053.html#a4717413
> Sent from the ActiveMQ - User forum at Nabble.com.
>
>


-- 

James
-------
http://radio.weblogs.com/0112098/