9 Replies Latest reply on Feb 17, 2008 3:49 PM by thangle

    Multiple persistence strategies in jbossMQ

      Hi,

      I'm trying to configure different persistence strategies for my JMS queues and topics in jboss 4.0.5. What I need to do is

      configure null persistance for the logging topic, and database persistance for the application queue. I hace seen this post

      in jboss forum

      http://www.jboss.org/index.html?module=bb&t=47828&op=viewtopic

      and performed all the steps it says, but haven't made it to work.

      These are the steps I have done:

      1) Set up null-persistence-service.xml in deploy/jms. Change all object names so that they don't collide with the jdbc

      persistence manager. That is, NullDestinationManager, NullMessageCache, and NullPersistenceManager. In this step I haven't

      specified a CacheStore object, because it is not specified in null persistence configuration.

      <mbean code="org.jboss.mq.server.jmx.DestinationManager" name="jboss.mq:service=NullDestinationManager">
       <depends optional-attribute-name="MessageCache">jboss.mq:service=NullMessageCache</depends>
       <depends optional-attribute-name="PersistenceManager">jboss.mq:service=NullPersistenceManager</depends>
       <depends optional-attribute-name="StateManager">jboss.mq:service=StateManager</depends>
       </mbean>
      
       <mbean code="org.jboss.mq.server.MessageCache"
       name="jboss.mq:service=NullMessageCache">
       <attribute name="HighMemoryMark">50</attribute>
       <attribute name="MaxMemoryMark">60</attribute>
       <attribute name="CacheStore">jboss.mq:service=NullPersistenceManager</attribute>
       </mbean>
      
       <mbean code="org.jboss.mq.pm.none.PersistenceManager"
       name="jboss.mq:service=NullPersistenceManager">
       </mbean>
      


      2) Create a 2nd invoker (NullInvoker) in jbossmq-service.xml that is a copy of the Invoker (with local versions of all

      configured interceptors.) NullInvoker uses NullDestinationManager.


       <!-- Null Invoker -->
       <mbean code="org.jboss.mq.server.jmx.Invoker" name="jboss.mq:service=NullInvoker">
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=NullTracingInterceptor</depends>
       <depends>jboss:service=Naming</depends>
       </mbean>
       <mbean code="org.jboss.mq.server.jmx.InterceptorLoader" name="jboss.mq:service=NullTracingInterceptor">
       <attribute name="InterceptorClass">org.jboss.mq.server.TracingInterceptor</attribute>
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=NullSecurityManager</depends>
       </mbean>
      
       <mbean code="org.jboss.mq.security.SecurityManager" name="jboss.mq:service=NullSecurityManager">
       <attribute name="DefaultSecurityConfig">
       <security>
       <role name="guest" read="true" write="true" create="true"/>
       </security>
       </attribute>
       <attribute name="SecurityDomain">java:/jaas/jbossmq</attribute>
       <depends optional-attribute-name="NextInterceptor">jboss.mq:service=NullDestinationManager</depends>
       </mbean>
      


      3) Point jvm-il-service.xml at NullInvoker instead of Invoker.


       <mbean code="org.jboss.mq.il.jvm.JVMServerILService"
       name="jboss.mq:service=InvocationLayer,type=JVM">
       <depends optional-attribute-name="Invoker">jboss.mq:service=NullInvoker</depends>
       <attribute name="ConnectionFactoryJNDIRef">java:/ConnectionFactory</attribute>
       <attribute name="XAConnectionFactoryJNDIRef">java:/XAConnectionFactory</attribute>
       <attribute name="PingPeriod">0</attribute>
       </mbean>
      


      4) Modify some of my local destinations to point at NullDestinationManager instead of DestinationManager.

       <mbean code="org.jboss.mq.server.jmx.Topic"
       name="jboss.mq.destination:service=Topic,name=LogginTopic">
       <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
       <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
       <attribute name="JNDIName">topic/SomCDRLog</attribute>
       </mbean>
      
       <mbean code="org.jboss.mq.server.jmx.Queue"
       name="jboss.mq.destination:service=Queue,name=ApplicationQueue">
       <depends optional-attribute-name="DestinationManager">jboss.mq:service=NullDestinationManager</depends>
       <!-- <depends optional-attribute-name="SecurityManager">jboss.mq:service=NullSecurityManager</depends> -->
       <attribute name="JNDIName">queue/SomExecutableQueue
       </attribute>
       </mbean>
      


      Then, I'm getting errors starting jboss that say

      javax.jms.InvalidDestinationException: The destination TOPIC.LogginTopic does not exist !

      I don't know what's going wrong, any help you can give me is appreciated.

      Thank you!

        • 1. Re: Multiple persistence strategies in jbossMQ

          I'm so sorry, The text has wrong format. I post it again in order to be readable. Thank you.

          1) Set up null-persistence-service.xml in deploy/jms. Change all object names so that they don't collide with the jdbc persistence manager. That is, NullDestinationManager, NullMessageCache, and NullPersistenceManager. In this step I haven't specified a CacheStore object, because it is not specified in null persistence configuration.

          <mbean code="org.jboss.mq.server.jmx.DestinationManager" name="jboss.mq:service=NullDestinationManager">
           <depends optional-attribute-name="MessageCache">jboss.mq:service=NullMessageCache</depends>
           <depends optional-attribute-name="PersistenceManager">jboss.mq:service=NullPersistenceManager</depends>
           <depends optional-attribute-name="StateManager">jboss.mq:service=StateManager</depends>
           </mbean>
          
           <mbean code="org.jboss.mq.server.MessageCache"
           name="jboss.mq:service=NullMessageCache">
           <attribute name="HighMemoryMark">50</attribute>
           <attribute name="MaxMemoryMark">60</attribute>
           <attribute name="CacheStore">jboss.mq:service=NullPersistenceManager</attribute>
           </mbean>
          
           <mbean code="org.jboss.mq.pm.none.PersistenceManager"
           name="jboss.mq:service=NullPersistenceManager">
           </mbean>
          


          2) Create a 2nd invoker (NullInvoker) in jbossmq-service.xml that is a copy of the Invoker (with local versions of all configured interceptors.) NullInvoker uses NullDestinationManager.

           <!-- Null Invoker -->
           <mbean code="org.jboss.mq.server.jmx.Invoker" name="jboss.mq:service=NullInvoker">
           <depends optional-attribute-name="NextInterceptor">jboss.mq:service=NullTracingInterceptor</depends>
           <depends>jboss:service=Naming</depends>
           </mbean>
          
           <mbean code="org.jboss.mq.server.jmx.InterceptorLoader" name="jboss.mq:service=NullTracingInterceptor">
           <attribute name="InterceptorClass">org.jboss.mq.server.TracingInterceptor</attribute>
           <depends optional-attribute-name="NextInterceptor">jboss.mq:service=NullSecurityManager</depends>
           </mbean>
          
           <mbean code="org.jboss.mq.security.SecurityManager" name="jboss.mq:service=NullSecurityManager">
           <attribute name="DefaultSecurityConfig">
           <security>
           <role name="guest" read="true" write="true" create="true"/>
           </security>
           </attribute>
           <attribute name="SecurityDomain">java:/jaas/jbossmq</attribute>
           <depends optional-attribute-name="NextInterceptor">jboss.mq:service=NullDestinationManager</depends>
           </mbean>
          


          3) Point jvm-il-service.xml at NullInvoker instead of Invoker.

           <mbean code="org.jboss.mq.il.jvm.JVMServerILService"
           name="jboss.mq:service=InvocationLayer,type=JVM">
           <depends optional-attribute-name="Invoker">jboss.mq:service=NullInvoker</depends>
           <attribute name="ConnectionFactoryJNDIRef">java:/ConnectionFactory</attribute>
           <attribute name="XAConnectionFactoryJNDIRef">java:/XAConnectionFactory</attribute>
           <attribute name="PingPeriod">0</attribute>
           </mbean>
          


          4) Modify some of my local destinations to point at NullDestinationManager instead of DestinationManager.

           <mbean code="org.jboss.mq.server.jmx.Topic"
           name="jboss.mq.destination:service=Topic,name=LogginTopic">
           <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
           <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
           <attribute name="JNDIName">topic/SomCDRLog</attribute>
           </mbean>
          
           <mbean code="org.jboss.mq.server.jmx.Queue"
           name="jboss.mq.destination:service=Queue,name=ApplicationQueue">
           <depends optional-attribute-name="DestinationManager">jboss.mq:service=NullDestinationManager</depends>
           <!-- <depends optional-attribute-name="SecurityManager">jboss.mq:service=NullSecurityManager</depends> -->
           <attribute name="JNDIName">queue/SomExecutableQueue
           </attribute>
           </mbean>
          


          Then, I'm getting errors starting jboss that say

          javax.jms.InvalidDestinationException: The destination TOPIC.LogginTopic does not exist !

          I don't know what's going wrong, any help you can give me is appreciated.

          Thank you!

          • 2. Re: Multiple persistence strategies in jbossMQ

            What you've done is to deploy two different JBossMQs so unless you are
            looking up the correct connection factory for the correct topic it is not suprising
            that you will get a topic not found error.

            If you read the wiki carefully, you'll see that the "NullPersistenceManager"
            can be setup with a *delegate* real persistence manager.
            http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigJBossMQNullPersistence

            <mbean code="org.jboss.mq.pm.none.PersistenceManager"
             name="jboss.mq:service=PersistenceManager">
            
             <!-- An optional delegate for real persistence of some destinations e.g. jdbc2 -->
             <!-- depends optional-attribute-name="DelegatePM">jboss.mq:service=SomePersistenceManager</depends-->
             </mbean>
            


            You can then choose which destinations are really persisted when you deploy them
            http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigTopic
            e.g.
             <mbean code="org.jboss.mq.server.jmx.Topic"
             name="jboss.mq.destination:service=Topic,name=InMemoryTopic">
             <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
             <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
             <attribute name="SecurityConf">
             <security>
             <role name="guest" read="true" write="true"/>
             <role name="publisher" read="true" write="true" create="false"/>
             </security>
             </attribute>
            
             <!-- HERE -->
             <attribute name="InMemory">true</attribute>
             </mbean>
            


            • 3. Re: Multiple persistence strategies in jbossMQ
              vincenttran

              Is it possible to store each queue's persistence in a separate database? That is what I am having trouble trying to figure out for a long time.

              Eg. I have QueueA, and QueueB, and I want QueueA's messages to be persisted to DatabaseA on Oracle, and I want QueueB's messages to be persisted to DatabaseB on Oracle.

              Thanks,
              Vincent

              • 4. Re: Multiple persistence strategies in jbossMQ

                No. Because that would require both databases to be XA and JBossMQ to use
                XA/JTA (two phase commit) internally on the two persistence managers.

                The jDBC2 PersistenceManager is not designed to do this.

                XA is implemented at the JMS Session level so you can do it with two different
                JBossMQ instances. But then you are back to having to know which ConnectionFactory
                needs to be used for which destination.

                • 5. Re: Multiple persistence strategies in jbossMQ
                  justinmiller

                   


                  You can then choose which destinations are really persisted when you deploy them
                  http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigTopic
                  e.g.
                  Code:

                  <mbean code="org.jboss.mq.server.jmx.Topic"
                  name="jboss.mq.destination:service=Topic,name=InMemoryTopic">
                  <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
                  <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
                  <attribute name="SecurityConf">
                  <security>
                  <role name="guest" read="true" write="true"/>
                  <role name="publisher" read="true" write="true" create="false"/>
                  </security>
                  </attribute>

                  <!-- HERE -->
                  <attribute name="InMemory">true</attribute>
                  </mbean>


                  If I use the NullPersistenceManager with a delegate, and set InMemory=false, will it still perform message softening?

                  Ideally, here's the situation I want:

                  For all queues and topics, I want both message persistence and softening. For select queues, I just want the message softening, but not persistence.

                  The wiki leads me to believe that this configuration isn't possible.

                  Any way I can achieve this?

                  • 6. Re: Multiple persistence strategies in jbossMQ

                     

                    "justinmiller" wrote:

                    Ideally, here's the situation I want:

                    For all queues and topics, I want both message persistence and softening. For select queues, I just want the message softening, but not persistence.

                    The wiki leads me to believe that this configuration isn't possible.

                    Any way I can achieve this?


                    What you describe is default behaviour for non-durable topic subscriptions
                    and queues that have only non-persitent messages.

                    I've said this a hundred times before in this forum:
                    PERSISTENCE IS A PROPERTY OF THE MESSAGE NOT THE QUEUE

                    If you don't trust the clients to send non-persistent message then you
                    can enforce such a policy on the server. e.g.
                    http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossMQInterceptorExample

                    • 7. Re: Multiple persistence strategies in jbossMQ
                      justinmiller

                      http://wiki.jboss.org/wiki/Wiki.jsp?page=DeliveryMode

                      This wiki page says it's an error to try and set the delivery mode on the message itself. Is this an error in the wiki?

                      Justin

                      • 8. Re: Multiple persistence strategies in jbossMQ

                        That's from the client side api BEFORE you send the message.
                        The MessageProducer.send() is what sets the DeliveryMode
                        (either from the passed parameter or the value you configure on the MessageProducer).

                        The interceptor runs AFTER the client api. You can modify the message
                        as much as you like there (with reason :-), as long as you do it before the
                        DestinationManager sees it.

                        • 9. Re: Multiple persistence strategies in jbossMQ
                          thangle

                           

                          "adrian@jboss.org" wrote:
                          What you've done is to deploy two different JBossMQs so unless you are
                          looking up the correct connection factory for the correct topic it is not suprising
                          that you will get a topic not found error.

                          If changing code is not an option, how can we avoid error Queue doesn't exist?

                          My requirement is just a little difference. Some queues are persisted locally using hsqldb-jdbc2. But there are queues need to be persisted to global database (oracle). We are using jboss4.0.3.SP1
                          Currently, I have two DMs. I tried to set attribute "NextInterceptor" for DestinationManager (DM1) defined in hsqldb-jdbc2 to DestinationManager (DM2)defined in oracle-jdbc2. The deployment works. From JMX web, I can see 2 DMs (but NextInterception of DM1 has service of PersistentManager defined in DM2 instead of DM2 itself???).

                          Scenario1: I deployed Queue-A with DM1. Messages got on Queue-A. But they were not persisted to oracle database. It indicates that NextInterceptor defined in DM1 is not working? Is it expected behavior? Do I need to do extra work to make NextInterceptor setting for DM works?

                          Scenario2: QueueA is registered to DM2. I got the same error javax.jms.InvalidDestinationException: The destination QUEUE.Queue-A doesn't exist (which is explained in above quote from Adrian). Can we have an option of failure tolerance in this queue lookup? Well, Queue-A was not in DM1 list but it was in DM2 list. If we let it pass here, the next interceptor in DM1 will call DM2 and it will see Queue-A there (of course, we assume next interceptor setting works in DM)