Context
The requirement is to create a clustered WebSphere MQ infrastructure, and then send messages to an application, known as a Message Driven Bean, deployed onto WebSphere Application Server.
The next step will be to create a more sophisticated application that can send and receive messages to/from WebSphere MQ, most likely leveraging the JavaEE Service Component Architecture.
In this scenario, I will create a pair of WMQ Queue Managers, each on a separate OS ( Red Hat VM ), one representing the Enterprise Service Bus (ESB), which will hold a full repository, and one representing IBM Business Process Manager, hosting a partial repository.
For me, the key lesson learned is that one creates a cluster Queue local to where it's actually used. In other words, because I need to interact with the clustered Queue on the BPM box, the queue needs to be hosted by the local ( to BPM ) Queue Manager.
WMQ Cluster Setup
Set up full repository on ESB box
Create Queue Manager
crtmqm ESB101_QM
Start Queue Manager
strmqm ESB101_QM
Start MQSC Environment
runmqsc ESB101_QM
Add a Repository Definition
ALTER QMGR REPOS(ESB101)
Define Listener
DEFINE LISTENER(TCP.LISTENER) TRPTYPE(tcp) CONTROL(qmgr) PORT(1414)
START LISTENER(TCP.LISTENER)
Define CLUSSDR Channel
DEFINE CHANNEL(BPM855) CHLTYPE(CLUSSDR) TRPTYPE(TCP) CONNAME('BPM855.UK.IBM.COM(1414)') CLUSTER(ESB101)
Define CLUSRCVR Channel
DEFINE CHANNEL(ESB101) CHLTYPE(CLUSRCVR) TRPTYPE(TCP) CONNAME('ESB.UK.IBM.COM(1414)') CLUSTER(ESB101)
Setup partial repository on BPM box
Create Queue Manager
crtmqm BPM855_QM
Start Queue Manager
strmqm BPM855_QM
Start MQSC Environment
runmqsc BPM855_QM
Define Listener
DEFINE LISTENER(TCP.LISTENER) TRPTYPE(tcp) CONTROL(qmgr) PORT(1414)
START LISTENER(TCP.LISTENER)
Define CLUSSDR Channel
DEFINE CHANNEL(ESB101) CHLTYPE(CLUSSDR) TRPTYPE(TCP) CONNAME('ESB.UK.IBM.COM(1414)') CLUSTER(ESB101)
Define CLUSRCVR Channel
DEFINE CHANNEL(BPM855) CHLTYPE(CLUSRCVR) TRPTYPE(TCP) CONNAME('BPM855.UK.IBM.COM(1414)') CLUSTER(ESB101)
Define Cluster Queue
DEFINE QLOCAL(ESB101_Q) CLUSTER(ESB101)
Change Authority for Queue and Queue Manager to allow the WAS user (wasadmin) to connect - BPM box
setmqaut -m BPM855_QM -t qmgr -p wasadmin +connect +inq +dsp
setmqaut -m BPM855_QM -t q -n ESB101_Q -p wasadmin +inq +browse +put
setmqaut -m BPM855_QM -t q -n ESB101_Q -p wasadmin +inq +browse +get
WMQ Cluster Testing
Put messages onto the cluster Queue - ESB box
/opt/mqm/samp/bin/amqsput ESB101_Q ESB101_QM
Sample AMQSPUT0 start
target queue is ESB101_Q
Hello
World
Sample AMQSPUT0 end
Get messages from the cluster queue - BPM box
/opt/mqm/samp/bin/amqsget ESB101_Q BPM855_QM
Sample AMQSGET0 start
message <Hello>
message <World>
no more messages
Sample AMQSGET0 end
WAS Message Driven Bean Setup - BPM box
Start WSAdmin client
/opt/IBM/WebSphere/AppServer/profiles/Dmgr01/bin/wsadmin.sh -lang jython -user wasadmin -password passw0rd
Update WAS MQ Provider to support local bindings ( need to add native path )
AdminTask.manageWMQ('"WebSphere MQ Resource Adapter(cells/bpm85Cell1/nodes/AppSrv01Node/servers/foobar|resources.xml#J2CResourceAdapter_1416556034607)"', '[-nativePath /opt/mqm/java/lib64/ -disableWMQ false ]')
AdminConfig.save()
AdminNodeManagement.syncActiveNodes()
Create J2C Authentication Alias for wasadmin user
AdminTask.setAdminActiveSecuritySettings('[-customProperties["com.ibm.websphere.security.JAASAuthData.removeNodeNameGlobal=true"]]')
AdminTask.createAuthDataEntry('[-alias wasadmin -user wasadmin -password passw0rd -description "WebSphere MQ Connectivity User" ]')
AdminConfig.save()
AdminNodeManagement.syncActiveNodes()
Create Queue and Activation Specification ( scoped to footer server )
AdminTask.createWMQQueue('foobar(cells/bpm85Cell1/nodes/AppSrv01Node/servers/foobar|server.xml)', '[-name ESB101_Q -jndiName jms/ESB101_Q -queueName ESB101_Q -qmgr -description ]')
AdminConfig.save()
AdminNodeManagement.syncActiveNodes()
AdminTask.createWMQActivationSpec('"WebSphere MQ JMS Provider(cells/bpm85Cell1/nodes/AppSrv01Node/servers/foobar|resources.xml#builtin_mqprovider)"', '[-name ESB101_AS -jndiName jms/ESB101_AS -description -destinationJndiName jms/ESB101_Q -destinationType javax.jms.Queue -messageSelector -qmgrName BPM855_QM -wmqTransportType BINDINGS -qmgrSvrconnChannel -qmgrHostname -authAlias wasadmin]')
AdminConfig.save()
AdminNodeManagement.syncActiveNodes()
Install Message Driven Bean
AdminApp.install('/home/wasadmin/SampleMDBEJB.ear', '[ -nopreCompileJSPs -distributeApp -nouseMetaDataFromBinary -nodeployejb -appname SampleMDBEJBEAR -createMBeansForResources -noreloadEnabled -nodeployws -validateinstall warn -noprocessEmbeddedConfig -filepermission .*\.dll=755#.*\.so=755#.*\.a=755#.*\.sl=755 -noallowDispatchRemoteInclude -noallowServiceRemoteInclude -asyncRequestDispatchType DISABLED -nouseAutoLink -noenableClientModule -clientMode isolated -novalidateSchema -MapModulesToServers [[ SampleMDBEJB SampleMDBEJB.jar,META-INF/ejb-jar.xml WebSphere:cell=bpm85Cell1,node=AppSrv01Node,server=foobar ]] -BindJndiForEJBMessageBinding [[ SampleMDBEJB SampleMDB SampleMDBEJB.jar,META-INF/ejb-jar.xml "" jms/ESB101_AS jms/ESB101_Q wasadmin ]]]' )
AdminConfig.save()
AdminNodeManagement.syncActiveNodes()
Restart Server
AdminControl.invoke('WebSphere:name=foobar,process=foobar,platform=proxy,node=AppSrv01Node,j2eeType=J2EEServer,version=8.5.5.2,type=Server,mbeanIdentifier=cells/bpm85Cell1/nodes/AppSrv01Node/servers/foobar/server.xml#Server_1416599363822,cell=bpm85Cell1,spec=1.0,processType=ManagedProcess', 'restart', '[]', '[]')
WMQ Cluster > MDB Testing
On ESB box
/opt/mqm/samp/bin/amqsput ESB101_Q ESB101_QM
Sample AMQSPUT0 start
target queue is ESB101_Q
Hello
WebSphere
From
WMQ
Sample AMQSPUT0 end
On BPM box
cat /opt/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/foobar/SystemOut.log
[22/11/14 07:57:30:958 GMT] 0000009d SystemOut O +++ SAMPLE MDB: Text Message => Hello
[22/11/14 07:57:36:271 GMT] 0000009d SystemOut O +++ SAMPLE MDB: Text Message => WebSphere
[22/11/14 07:57:38:475 GMT] 0000009d SystemOut O +++ SAMPLE MDB: Text Message => From
[22/11/14 07:57:40:350 GMT] 0000009d SystemOut O +++ SAMPLE MDB: Text Message => WMQ
Notes and Lessons Learned - 1
The credentials specified in the J2C Authentication Alias are crucial. At one point, I mis-specified the password, and saw the following exceptions in the WAS SystemOut.log : -
eMDBEJBEAR application is bound to the jms/ESB101_AS activation specification.
[22/11/14 08:01:38:857 GMT] 00000081 SibMessage W [:] CWSJY0003W: MQJCA4023: Startup reconnection failed for ActivationSpec 'javax.jms.Queue:jms/ESB101_Q@BPM855_QM <1648233785>'. Exception details: '
Message : com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'BPM855_QM' with connection mode 'Bindings' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
Caused by [1] --> Message : com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
[22/11/14 08:01:38:864 GMT] 00000081 ActivationSpe E J2CA0138E: The Message Endpoint activation failed for ActivationSpec jms/ESB101_AS (com.ibm.mq.connector.inbound.ActivationSpecImpl) and MDB application SampleMDBEJBEAR#SampleMDBEJB.jar#SampleMDB due to the following exception: com.ibm.mq.connector.DetailedResourceAdapterInternalException: MQJCA1011: Failed to allocate a JMS connection. An internal error caused an attempt to allocate a connection to fail. See the linked exception for details of the failure.
Caused by: com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'BPM855_QM' with connection mode 'Bindings' and host name 'localhost(1414)'.
Please check if the supplied username and password are correct on the QueueManager to which you are connecting.
[22/11/14 08:01:38:883 GMT] 00000081 RAWrapperImpl E J2CA0089E: The method activateEndpoint on ResourceAdapter JavaBean cells/bpm85Cell1/nodes/AppSrv01Node/servers/foobar/resources.xml#J2CResourceAdapter_1416556034607 failed with the following exception: com.ibm.mq.connector.DetailedResourceAdapterInternalException: MQJCA1011: Failed to allocate a JMS connection. An internal error caused an attempt to allocate a connection to fail. See the linked exception for details of the failure.
with this in the WMQ log - /var/mqm/qmgrs/BPM855_QM/errors/AMQERR01.LOG - for the local ( to WAS ) Queue Manager: -
AMQ5534: User ID 'wasadmin' authentication failed
EXPLANATION:
The user ID and password supplied by 'java' could not be authenticated.
AMQ5542: The failed authentication check was caused by the queue manager
CONNAUTH CHCKLOCL(OPTIONAL) configuration.
EXPLANATION:
The user ID 'wasadmin' and its password were checked because the queue manager
connection authority (CONNAUTH) configuration refers to an authentication
information (AUTHINFO) object named 'SYSTEM.DEFAULT.AUTHINFO.IDPWOS' with
CHCKLOCL(OPTIONAL).
I previously wrote about this here: -
in the context of the IBM Integration Bus Toolkit connecting to WMQ.
Bottom line, credentials are important :-)
Notes and Lessons Learned - 2
The biggest mistake I made was to assume that it was necessary to create the cluster Queue ( ESB101_Q of type QLOCAL ) on the ESB box. I spent many a fine hour trying to work out why things didn't work.
The point is that a client application ( amqsget or the MDB ) cannot connect to/use a Queue that's on a Queue Manager that's NOT local to the client. I'd assumed that I could make a bindings connection ( client to Queue Manager directly, without creating a client connection / channels etc. ) to a Queue Manager that's NOT local to the client/application.
This is why I do this job, every day is a school day, and I love to learn ...... :-)
No comments:
Post a Comment