4 Replies Latest reply on Jan 3, 2010 11:00 PM by Yong Yao

    Problem with creating bridge in clustered configuration.

    Maciej Skorupka Newbie

      Hi,

       

      This post relates to this one http://community.jboss.org/thread/146243?tstart=0 and bases on description on http://community.jboss.org/wiki/JBMBridgeConfiguration and http://labs.jboss.com/file-access/default/members/jbossmessaging/freezone/docs/userguide-1.4.3.GA/html_single/index.html#bridge

       

      We're working on clustered JBoss 5.1 (2 nodes) working as a JMS server with one clustered queue (ECM-PRM-Queue). We have two other JBoss 5.1 - one is producer (ECM) and one is consumer (PRM) of messages and both use modified default configuration. There are two bridges - one on producer's JBoss (ECM-PRM-Bridge) and one on consumer's JBoss. There are local queues on both producer's (ECM-PRM-BridgedQueue) and consumer's server. Bridges copy messages automatically from producer's queue, to clustered queue. Then consumer's bridge copies messages to its local queue. At least we're trying to accomplish this. So what's the problem?

       

      When producer puts something to its queue, bridge automatically tries to send them to remote queue on cluster, but error occurs:

       

      10:38:43,681 WARN  [Bridge] jboss.messaging:name=ECM-PRM-Bridge,service=Bridge Failed to set up connections javax.jms.JMSSecurityException: User ecm-role is NOT authenticated

       

      The same thing appears when "ecm-user" is used as a username (of course then "ecm-role" is "ecm-role"). So, basically, there's a problem with authentication. http://community.jboss.org/wiki/JBMBridgeConfiguration says that we can add RemoteJMSProvider to jms-ds.xml file, but http://labs.jboss.com/file-access/default/members/jbossmessaging/freezone/docs/userguide-1.4.3.GA/html_single/index.html#bridge mentions:

       

      This is the object name of the JMSProviderLoader MBean that the       bridge will use to lookup the source connection factory and source       destination.

      By default JBoss AS ships with one JMSProviderLoader, deployed in       the file jms-ds.xml - this is the default local       JMSProviderLoader. (This would be in       hajndi-jms-ds.xml in a clustered       configuration)

      If your source destination is on different servers or even       correspond to a different, non JBoss JMS provider, then you can deploy       another JMSProviderLoader MBean instance which references the remote JMS       provider, and reference that from this attribute. The bridge would then       use that remote JMS provider to contact the source destination

      Note that if you are using a remote non JBoss Messaging source or       target and you wish once and only once delivery then that remote JMS       provider must provide a fully functional JMS XA resource implementation       that works remotely from the server - it is known that some non JBoss       JMS providers do not provide such a resource

       

      which suggests that hajndi-jms-ds.xml should be used in case when target queue is on cluster. At least, I understand it this way. Where's that file? How to create it? What is it for? I thought that HA-JNDI is used by default on clustered configuration - each node in cluster has it on port 1099 by default. So we've added RemoteJMSProvider to jms-ds.xml.

       

      DETAILS OF CONFIGURATION:

      Clustered queue is created on both nodes of cluster in destinations-service.xml:

       

      <mbean code="org.jboss.jms.server.destination.QueueService"
              name="jboss.messaging.destination:service=Queue,name=ECM-PRM-Queue"
              xmbean-dd="xmdesc/Queue-xmbean.xml">
          <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
          <depends>jboss.messaging:service=PostOffice</depends>
          <attribute name="Clustered">true</attribute>
          <attribute name="SecurityConfig">
              <security>
                  <role name="ecm-role" write="true" />
                  <role name="prm-role" read="true" />
              </security>
          </attribute>
      </mbean>

       

      So "ecm-role" should be capable of writing messages to that queue. Producer has a queue in destinations-service.xml:

       

      <mbean code="org.jboss.jms.server.destination.QueueService"
            name="jboss.messaging.destination:service=Queue,name=ECM-PRM-BridgedQueue"
            xmbean-dd="xmdesc/Queue-xmbean.xml">
            <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
            <depends>jboss.messaging:service=PostOffice</depends>
              <attribute name="SecurityConfig">
                  <security>
                      <role name="ecm-role" read="true" write="true" />
                  </security>
              </attribute>
         </mbean>

       

      Producer also has a bridge service defined in deploy/messaging/ecmprm-bridge-service.xml:

       


          <mbean code="org.jboss.jms.server.bridge.BridgeService"
                name="jboss.messaging:service=Bridge,name=ECM-PRM-Bridge"
                xmbean-dd="xmdesc/Bridge-xmbean.xml">
               
            <!-- The JMS provider loader that is used to lookup the source destination -->  
            <depends optional-attribute-name="SourceProviderLoader">
                jboss.messaging:service=JMSProviderLoader,name=JMSProvider</depends>
           
            <!-- The JMS provider loader that is used to lookup the target destination -->
            <depends optional-attribute-name="TargetProviderLoader">
                jboss.messaging:service=JMSProviderLoader,name=RIRemoteJMSProvider</depends>   
           
            <!-- The JNDI lookup for the source destination -->
            <attribute name="SourceDestinationLookup">/queue/ECM-PRM-BridgedQueue</attribute>
           
            <!-- The JNDI lookup for the target destination -->
            <attribute name="TargetDestinationLookup">/queue/ECM-PRM-Queue</attribute>
           
            <!-- The username to use for the source connection       -->
            <attribute name="SourceUsername">ecm-role</attribute>
           
            <!-- The password to use for the source connection      -->
            <attribute name="SourcePassword">ecm-user</attribute>

           
            <!-- The username to use for the target connection      -->
            <attribute name="TargetUsername">ecm-role</attribute>


            <!-- The password to use for the target connection      -->
            <attribute name="TargetPassword">ecm-user</attribute>

       

      "ecm-role" is a role connected with "ecm-user" which has "ecm-user" as a password. This user and roles exist on both producer and cluster. We've also used "ecm-user" as username in both places. We've added RemoteJMSProvider to deploy/messaging/jms-ds.xml:

       

      <!-- Remote JMS provider -->

      <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
          name="jboss.messaging:service=JMSProviderLoader,name=RIRemoteJMSProvider">
          <attribute name="ProviderName">RemoteJMSProvider</attribute>
          <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
          <!-- The connection factory -->
          <attribute name="FactoryRef">java:/ClusteredConnectionFactory</attribute>
          <!-- The queue connection factory -->
          <attribute name="QueueFactoryRef">java:/ClusteredConnectionFactory</attribute>
          <!-- The topic factory -->
          <attribute name="TopicFactoryRef">java:/ClusteredConnectionFactory</attribute>
          <!-- Connect to JNDI on the host "the-remote-host-name" port 1099-->
          <attribute name="Properties">
            java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
            java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
            java.naming.provider.url=jnp://192.168.107.51:1099,192.168.107.68:1099
          </attribute>
      </mbean>

       

      Do we have to use "java:/ClusteredConnectionFactory" here? Or maybe "/ClusteredConnectionFactory" or "/XAConnectionFactory"? If one of them suits best, why is it so?