4 Replies Latest reply on Feb 2, 2006 1:33 PM by Ovidiu Feodorov

    Running JBossMQ in simple unit tests using the Microcontaine

    Adrian Brock Master

      FYI: You can do this using the followng Microcontainer config against JBossMQ in head.

      <?xml version="1.0" encoding="UTF-8"?>
      
      <deployment xmlns="urn:jboss:bean-deployer:2.0">
      
       <bean name="PersistenceManager" class="org.jboss.mq.pm.none.PersistenceManager"/>
      
       <bean name="StateManager" class="org.jboss.mq.sm.none.NullStateManager"/>
      
       <bean name="MessageCache" class="org.jboss.mq.kernel.MessageCache">
       <property name="persistenceManager"><inject bean="PersistenceManager"/></property>
       </bean>
      
       <bean name="DestinationManager" class="org.jboss.mq.kernel.DestinationManager">
       <property name="persistenceManagerInstance"><inject bean="PersistenceManager"/></property>
       <property name="stateManagerInstance"><inject bean="StateManager"/></property>
       <property name="messageCacheInstance"><inject bean="MessageCache"/></property>
       </bean>
      
       <bean name="JMSServer">
       <constructor factoryMethod="getInterceptor">
       <factory bean="DestinationManager"/>
       </constructor>
       </bean>
      
       <bean name="Invoker" class="org.jboss.mq.server.JMSServerInvoker">
       <property name="next"><inject bean="JMSServer"/></property>
       </bean>
      
       <bean name="ServerIL" class="org.jboss.mq.il.jvm.JVMServerIL">
       <constructor>
       <parameter><inject bean="Invoker"/></parameter>
       </constructor>
       </bean>
      
       <bean name="GCF" class="org.jboss.mq.GenericConnectionFactory">
       <constructor>
       <parameter><inject bean="ServerIL"/></parameter>
       <parameter>
       ClientILService=org.jboss.mq.il.jvm.JVMClientILService
       </parameter>
       </constructor>
       </bean>
      
       <bean name="Queue" class="org.jboss.mq.SpyQueue">
       <constructor>
       <parameter>testQueue</parameter>
       </constructor>
       </bean>
      
       <bean name="RealQueue" class="org.jboss.mq.server.JMSQueue">
       <constructor>
       <parameter><inject bean="Queue"/></parameter>
       <parameter><null/></parameter>
       <parameter><inject bean="JMSServer"/></parameter>
       <parameter><inject bean="JMSServer" property="parameters"/></parameter>
       </constructor>
       <install bean="JMSServer" method="addDestination">
       <parameter><this/></parameter>
       </install>
       <uninstall bean="JMSServer" method="closeDestination">
       <parameter><inject bean="Queue"/></parameter>
       </uninstall>
       </bean>
      
       <bean name="ConnectionFactory" class="org.jboss.mq.SpyConnectionFactory">
       <constructor>
       <parameter><inject bean="GCF"/></parameter>
       </constructor>
       </bean>
      
      </deployment>
      


      NOTE: This config does NOT have security, persistence or support durable subscription
      operations.

      A simple unit test would look like this
      (assuming the above config is in org/jboss/test/JBossMQUnitTestCase.xml)
      /*
      * JBoss, Home of Professional Open Source
      * Copyright 2006, JBoss Inc., and individual contributors as indicated
      * by the @authors tag. See the copyright.txt in the distribution for a
      * full listing of individual contributors.
      *
      * This is free software; you can redistribute it and/or modify it
      * under the terms of the GNU Lesser General Public License as
      * published by the Free Software Foundation; either version 2.1 of
      * the License, or (at your option) any later version.
      *
      * This software is distributed in the hope that it will be useful,
      * but WITHOUT ANY WARRANTY; without even the implied warranty of
      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      * Lesser General Public License for more details.
      *
      * You should have received a copy of the GNU Lesser General Public
      * License along with this software; if not, write to the Free
      * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
      * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
      */
      package org.jboss.test;
      
      import javax.jms.Connection;
      import javax.jms.ConnectionFactory;
      import javax.jms.Message;
      import javax.jms.MessageConsumer;
      import javax.jms.MessageProducer;
      import javax.jms.Queue;
      import javax.jms.Session;
      
      import junit.framework.Test;
      
      import org.jboss.test.kernel.junit.MicrocontainerTest;
      
      /**
       * JMS Unit Tests
       *
       * @author <a href="mailto:adrian@jboss.com">Adrian Brock</a>
       * @version $Revision: 1.3 $
       */
      public class JBossMQUnitTestCase extends MicrocontainerTest
      {
       public void testNoTx() throws Throwable
       {
       ConnectionFactory cf = (ConnectionFactory) getBean("ConnectionFactory");
       Queue queue = (Queue) getBean("Queue");
       Connection c = cf.createConnection();
       try
       {
       c.start();
       Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
       Message m = s.createTextMessage("hello");
      
       MessageProducer p = s.createProducer(queue);
       p.send(m);
      
       MessageConsumer r = s.createConsumer(queue);
       m = r.receiveNoWait();
       getLog().info(m);
       }
       finally
       {
       c.close();
       }
       }
      
       public static Test suite() throws Exception
       {
       return suite(JBossMQUnitTestCase.class);
       }
      
       public JBossMQUnitTestCase (String name)
       {
       super(name);
       }
      }
      


      With the following output:
      0 DEBUG [JBossMQUnitTestCase] ==== setUp org.jboss.test.JBossMQUnitTestCase ====
      86 DEBUG [KernelFactory] Starting JBoss Kernel construction...
      415 DEBUG [KernelFactory] Completed JBoss Kernel construction. Duration: 327 milliseconds
      507 DEBUG [JBossMQUnitTestCase] Deploying file:/home/ejort/jboss-head/workspace/rars/src/resources/tests/org/jboss/test/JBossMQUnitTestCase.
      xml
      3527 DEBUG [PersistenceManager] Creating PersistenceManager
      3529 DEBUG [PersistenceManager] Created PersistenceManager
      3534 DEBUG [PersistenceManager] Starting PersistenceManager
      3538 DEBUG [PersistenceManager] Started PersistenceManager
      3597 DEBUG [NullStateManager] Creating NullStateManager
      3598 DEBUG [NullStateManager] Created NullStateManager
      3599 DEBUG [NullStateManager] Starting NullStateManager
      3600 DEBUG [NullStateManager] Started NullStateManager
      4124 DEBUG [JBossMQUnitTestCase] ==== Starting testNoTx ====
      4167 DEBUG [Connection] Setting the thread pool
      4171 DEBUG [Connection] org.jboss.mq.connectionThreadPoolFactory=org.jboss.mq.threadpool.ThreadPoolFactory
      4173 DEBUG [Connection] Client(2)
      4175 DEBUG [Connection] Setting the clockDaemon's thread factory
      4420 INFO [JBossMQUnitTestCase] SpyTextMessage {
      Header {
       jmsDestination : QUEUE.testQueue
       jmsDeliveryMode : 2
       jmsExpiration : 0
       jmsPriority : 4
       jmsMessageID : ID:1-11388827625501
       jmsTimeStamp : 1138882762550
       jmsCorrelationID: null
       jmsReplyTo : null
       jmsType : null
       jmsRedelivered : false
       jmsProperties : {JMSXDeliveryCount=1}
       jmsPropReadWrite: false
       msgReadOnly : true
       producerClientId: ID:1
      }
      Body {
       text :hello
      }
      }
      4430 DEBUG [JBossMQUnitTestCase] testNoTx took 305ms
      4431 DEBUG [JBossMQUnitTestCase] ==== Stopping testNoTx ====
      4432 DEBUG [JBossMQUnitTestCase] ==== tornDown org.jboss.test.JBossMQUnitTestCase ====
      4441 DEBUG [JMSDestinationManager] Closing destination QUEUE.testQueue
      4459 DEBUG [MessageCache] Thread exiting.
      4462 DEBUG [NullStateManager] Stopping NullStateManager
      4464 DEBUG [NullStateManager] Stopped NullStateManager
      4465 DEBUG [NullStateManager] Destroying NullStateManager
      4466 DEBUG [NullStateManager] Destroyed NullStateManager
      4467 DEBUG [PersistenceManager] Stopping PersistenceManager
      4468 DEBUG [PersistenceManager] Stopped PersistenceManager
      4469 DEBUG [PersistenceManager] Destroying PersistenceManager
      4470 DEBUG [PersistenceManager] Destroyed PersistenceManager
      


        • 1. Re: Running JBossMQ in simple unit tests using the Microcont
          Adrian Brock Master

          Now we need an equivalent for JBoss Messaging ;-)

          • 2. Re: Running JBossMQ in simple unit tests using the Microcont
            Ovidiu Feodorov Master

            We're currently using the ServiceContainer (org.jboss.test.messaging.tools.jmx.ServiceContainer), the micro-micro-container that we talked long time ago about, that allows us to test pretty much anything we need and we could possibly think of.

            Currently we have in place a simple mechanism that reads the sample "jboss-service.xml" configuration file, parses it and extracts the server/plug ins configuration, "deploys" them, while configuring them in the process with the default values we use to ship the sample file with, and then pounds them with tests (about 2500 of them :))

            This is how the tested/shipped/real configuration file looks like:

            .../jboss-head/jms/src/etc/server/default/deploy/jboss-messaging-service.xml

            <?xml version="1.0" encoding="UTF-8"?>
            
            <!--
             The JBoss Messaging service deployment descriptor.
            
             $Id: jboss-messaging-service.xml,v 1.31 2006/02/01 17:38:29 timfox Exp $
             -->
            
            <server>
            
             <!--
             <loader-repository>jboss.messaging:loader=ScopedLoaderRepository
             <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
             </loader-repository>
             -->
            
             <!-- JBoss 5 has a remoting connector already deployed. For JBoss 4, I need to deploy it. -->
             <!--
             <mbean code="org.jboss.remoting.transport.Connector"
             xmbean-dd="org/jboss/remoting/transport/Connector.xml"
             name="jboss.messaging:service=Connector,transport=socket"
             display-name="Socket transport Connector">
             <attribute name="Configuration">
             <config>
             <invoker transport="socket">
             <attribute name="marshaller" isParam="true">org.jboss.jms.server.remoting.JMSWireFormat</attribute>
             <attribute name="unmarshaller" isParam="true">org.jboss.jms.server.remoting.JMSWireFormat</attribute>
             <attribute name="serializationtype" isParam="true">jms</attribute>
             <attribute name="dataType" isParam="true">jms</attribute>
             <attribute name="socketTimeout">0</attribute>
             <attribute name="serverBindAddress">${jboss.bind.address}</attribute>
             <attribute name="serverBindPort">4457</attribute>
             </invoker>
             <handlers>
             <handler subsystem="JMS">org.jboss.jms.server.remoting.JMSServerInvocationHandler</handler>
             </handlers>
             </config>
             </attribute>
             <depends>jboss.messaging:service=NetworkRegistry</depends>
             </mbean>
            
             <mbean code="org.jboss.remoting.network.NetworkRegistry"
             name="jboss.messaging:service=NetworkRegistry"/>
             -->
            
             <!-- The Server Peer -->
             <mbean code="org.jboss.jms.server.ServerPeer"
             name="jboss.messaging:service=ServerPeer"
             xmbean-dd="xmdesc/ServerPeer-xmbean.xml">
            
             <constructor>
             <!-- ServerPeerID -->
             <arg type="java.lang.String" value="server.0" />
             <!-- DefaultQueueJNDIContext -->
             <arg type="java.lang.String" value="/queue" />
             <!-- DefaultTopicJNDIContext -->
             <arg type="java.lang.String" value="/topic" />
             </constructor>
            
             <depends optional-attribute-name="Connector">jboss.remoting:service=Connector,transport=socket</depends>
             <depends optional-attribute-name="ThreadPool">jboss.messaging:service=ThreadPool</depends>
             <depends optional-attribute-name="TransactionLog">jboss.messaging:service=TransactionLog</depends>
             <depends optional-attribute-name="MessageStore">jboss.messaging:service=MessageStore</depends>
             <depends optional-attribute-name="DurableSubscriptionStore">jboss.messaging:service=DurableSubscriptionStore</depends>
            
             <attribute name="SecurityDomain">java:/jaas/messaging</attribute>
             <attribute name="DefaultSecurityConfig">
             <security>
             <role name="guest" read="true" write="true" create="true"/>
             </security>
             </attribute>
             </mbean>
            
             <!-- Plug-ins -->
            
             <mbean code="org.jboss.jms.server.plugin.DefaultThreadPool"
             name="jboss.messaging:service=ThreadPool"
             xmbean-dd="xmdesc/DefaultThreadPool-xmbean.xml">
             <constructor>
             <!-- the default pool size -->
             <arg type="int" value="40" />
             </constructor>
             </mbean>
            
             <mbean code="org.jboss.messaging.core.plugin.JDBCTransactionLog"
             name="jboss.messaging:service=TransactionLog"
             xmbean-dd="xmdesc/JDBCTransactionLog-xmbean.xml">
            
             <!-- TODO this insures the fact that dependency exists. However I need to redundantly specifiy
             the DataSource JNDI name in order to actually get a reference to it. Fix this.
             -->
             <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
             <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
             <attribute name="DataSource">java:/DefaultDS</attribute>
             </mbean>
            
             <mbean code="org.jboss.messaging.core.plugin.JDBCMessageStore"
             name="jboss.messaging:service=MessageStore"
             xmbean-dd="xmdesc/JDBCMessageStore-xmbean.xml">
             <constructor>
             <!-- StoreID -->
             <arg type="java.lang.String" value="store.0" />
             </constructor>
             <!-- TODO this insures the fact that dependency exists. However I need to redundantly specifiy
             the DataSource JNDI name in order to actually get a reference to it. Fix this.
             -->
             <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
             <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
             <attribute name="DataSource">java:/DefaultDS</attribute>
             </mbean>
            
             <mbean code="org.jboss.jms.server.plugin.JDBCDurableSubscriptionStore"
             name="jboss.messaging:service=DurableSubscriptionStore"
             xmbean-dd="xmdesc/JDBCDurableSubscriptionStore-xmbean.xml">
            
             <!-- TODO this insures the fact that dependency exists. However I need to redundantly specifiy
             the DataSource JNDI name in order to actually get a reference to it. Fix this.
             -->
             <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
             <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
             <attribute name="DataSource">java:/DefaultDS</attribute>
             </mbean>
            
             <!-- ConnectionFactories -->
            
             <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory"
             name="jboss.messaging.destination:service=ConnectionFactory"
             xmbean-dd="xmdesc/ConnectionFactory-xmbean.xml">
             <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
             <attribute name="JNDIBindings">
             <bindings>
             <binding>/ConnectionFactory</binding>
             <binding>/XAConnectionFactory</binding>
             <binding>java:/ConnectionFactory</binding>
             <binding>java:/XAConnectionFactory</binding>
             </bindings>
             </attribute>
             </mbean>
            
             <!-- Test destinations -->
            
             <mbean code="org.jboss.jms.server.destination.Topic"
             name="jboss.messaging.destination:service=Topic,name=testTopic"
             xmbean-dd="xmdesc/Topic-xmbean.xml">
             <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
             <attribute name="SecurityConfig">
             <security>
             <role name="guest" read="true" write="true"/>
             <role name="publisher" read="true" write="true" create="false"/>
             <role name="durpublisher" read="true" write="true" create="true"/>
             </security>
             </attribute>
             </mbean>
            
             .....
            
             <!-- We need this to deploy MDBs -->
            
             <mbean code="org.jboss.jms.server.destination.Queue"
             name="jboss.messaging.destination:service=Queue,name=DLQ"
             xmbean-dd="xmdesc/Queue-xmbean.xml">
             <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
             </mbean>
            
            
             .....
            
            </server>
            
            
            


            The current testing mechanism supports everything (including security, persistence and durable subscription operations). From JBoss Messaging's perspective, the testing managed environment isn't any different than a real JMX microkernel instance.

            However, I am looking forward to integrate/replace(?) this with the proper Microcontainer support. It should be a relative simple translation at syntactic level, since all the semantics we need is already there.

            • 3. Re: Running JBossMQ in simple unit tests using the Microcont
              Adrian Brock Master

               

              "ovidiu.feodorov@jboss.com" wrote:

              Currently we have in place a simple mechanism that reads the sample "jboss-service.xml" configuration file, parses it and extracts the server/plug ins configuration, "deploys" them, while configuring them in the process with the default values


              You guys crack me up. I expect you to write a JVM next because you found an
              annoying bug and don't want to wait for Sun to fix it. :-)


              The current testing mechanism supports everything (including security, persistence and durable subscription operations).


              I wasn't meaning that it is a limitation of JBossMQ. :-)
              JBossMQ already runs in EJB3 embedded with real persistence, etc.

              It was a requirement.
              i.e. I don't want to reference external files or even bootstrap in memory hypersonic
              to use JBoss Messaging as a "mock" jms in my unit tests.

              If you want JBoss Messaging to run in EJB3 embedded instead
              (which I think should be our plan), then you'll need an MC config to bootstrap it.
              You should work with will Bill at getting it in the next release candidate.

              • 4. Re: Running JBossMQ in simple unit tests using the Microcont
                Ovidiu Feodorov Master

                No, not a JVM :)

                If you want JBoss Messaging to run in EJB3 embedded instead
                (which I think should be our plan), then you'll need an MC config to bootstrap it.
                You should work with will Bill at getting it in the next release candidate.


                Yes. It is scheduled. Will do.