Problem with creating bridge in clustered configuration.
mskorupka Dec 29, 2009 5:57 AMHi,
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?