在云上连接到IBM MQ的问题

时间:2019-02-22 06:52:15

标签: ibm-mq

在IBM Cloud上创建了IBM MQ,并尝试与IBM提供的JMS客户端连接。授权失败。

同一程序可在我的本地队列管理器上运行。任何见解都会帮助我探索云上的IBM MQ。

  • 环境= JDK 1.8
  • MQ客户端Jar = 9

我给了应用程序用户名/ API密钥,不确定为什么不连接

遵循的IBM文档 https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.sec.doc/q118680_.htm https://developer.ibm.com/messaging/learn-mq/mq-tutorials/develop-mq-jms/

异常跟踪

Exception in thread "main" 

com.ibm.msg.client.jms.DetailedJMSSecurityRuntimeException: JMSWMQ2007: Failed to send a message to destination 'RequestQ'.
JMS attempted to perform an MQPUT or MQPUT1; however IBM MQ reported an error.
Use the linked exception to determine the cause of this error.
    at com.ibm.msg.client.jms.DetailedJMSSecurityException.getUnchecked(DetailedJMSSecurityException.java:270)
    at com.ibm.msg.client.jms.internal.JmsErrorUtils.convertJMSException(JmsErrorUtils.java:173)
    at com.ibm.msg.client.jms.internal.JmsProducerImpl.send(JmsProducerImpl.java:633)
    at com.ibm.mq.samples.jms.JmsPutGet.main(JmsPutGet.java:122)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').

/*
* (c) Copyright IBM Corporation 2018
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.ibm.mq.samples.jms;


import javax.jms.Destination;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSProducer;
import javax.jms.TextMessage;

import com.ibm.mq.constants.MQConstants;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsConstants;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;

/**
 * A minimal and simple application for Point-to-point messaging.
 *
 * Application makes use of fixed literals, any customisations will require
 * re-compilation of this source file. Application assumes that the named queue
 * is empty prior to a run.
 *
 * Notes:
 *
 * API type: JMS API (v2.0, simplified domain)
 *
 * Messaging domain: Point-to-point
 *
 * Provider type: IBM MQ
 *
 * Connection mode: Client connection
 *
 * JNDI in use: No
 *  ReadMe -CompatibleMode
 *  
 */

public class JmsPutGet {

	// System exit status value (assume unset value to be 1)
	private static int status = 1;
	private static final String HOST = "ibm hostname"; // Host name or IP address
	private static final int PORT = 32442; // Listener port for your queue manager
	private static final String CHANNEL = "xxx.APP.SVRCONN"; //.APP.SVRCONN"; // Channel name
	private static final String QMGR = "QMxxx"; // Queue manager name
	private static final String APP_USER = "appusername"; // User name that application uses to connect to MQ
	private static final String APP_PASSWORD = "IBM API Key"; // Password that the application uses to connect to MQ
	private static final String QUEUE_NAME = "TestRequestQ"; // Queue that the application uses to put and get messages to and from
	
	/**
	 * Main method
	 *
	 * @param args
	 */
	public static void main(String[] args) {

		// Variables
		JMSContext context = null;
		Destination destination = null;
		JMSProducer producer = null;
		JMSConsumer consumer = null;



		try {
			// Create a connection factory
			JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
			JmsConnectionFactory cf = ff.createConnectionFactory();

			// Set the properties
			cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, HOST);
			cf.setIntProperty(WMQConstants.WMQ_PORT, PORT);
			cf.setStringProperty(WMQConstants.WMQ_CHANNEL, CHANNEL);
			cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
			cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, QMGR);
			cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "JmsPutGet (JMS)");
			cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
			cf.setStringProperty(WMQConstants.USERID, APP_USER);
			cf.setStringProperty(WMQConstants.PASSWORD, APP_PASSWORD);
			/*cf.setBooleanProperty(JmsConstants.USER_AUTHENTICATION_MQCSP, false);*/
			/*cf.setBooleanProperty(MQConstants.USE_MQCSP_AUTHENTICATION_PROPERTY, false);*/
			/*cf.setBooleanProperty("WMQConstants.USER_AUTHENTICATION_MQCSP",false);*/
			

			// Create JMS objects
			context = cf.createContext();
			destination = context.createQueue("queue:///" + QUEUE_NAME);

			long uniqueNumber = System.currentTimeMillis() % 1000;
			TextMessage message = context.createTextMessage("Your lucky number today is " + uniqueNumber);

			producer = context.createProducer();
			producer.send(destination, message);
			System.out.println("Sent message:\n" + message);

			consumer = context.createConsumer(destination); // autoclosable
			String receivedMessage = consumer.receiveBody(String.class, 15000); // in ms or 15 seconds

			System.out.println("\nReceived message:\n" + receivedMessage);

			recordSuccess();
		} catch (JMSException jmsex) {
			recordFailure(jmsex);
		}

		System.exit(status);

	} // end main()

	/**
	 * Record this run as successful.
	 */
	private static void recordSuccess() {
		System.out.println("SUCCESS");
		status = 0;
		return;
	}

	/**
	 * Record this run as failure.
	 *
	 * @param ex
	 */
	private static void recordFailure(Exception ex) {
		if (ex != null) {
			if (ex instanceof JMSException) {
				processJMSException((JMSException) ex);
			} else {
				System.out.println(ex);
			}
		}
		System.out.println("FAILURE");
		status = -1;
		return;
	}

	/**
	 * Process a JMSException and any associated inner exceptions.
	 *
	 * @param jmsex
	 */
	private static void processJMSException(JMSException jmsex) {
		System.out.println(jmsex);
		Throwable innerException = jmsex.getLinkedException();
		if (innerException != null) {
			System.out.println("Inner exception(s):");
		}
		while (innerException != null) {
			System.out.println(innerException);
			innerException = innerException.getCause();
		}
		return;
	}

}

2 个答案:

答案 0 :(得分:0)

最可能的原因可能是试图通过“ CLOUD.APP.SVRCONN”通道获取/放入队列中的消息的用户没有正确的访问权限。默认情况下,通道身份验证记录可能会阻止该用户获取GET / PUT消息。

解决方案

  1. 尝试使用“ CLOUD.ADMIN.SVRCONN”,您的应用程序现在应该可以获取/放置消息。

  2. 在CLOUD.APP.SVRCONN的通道身份验证记录中为用户提供适当的访问权限。

答案 1 :(得分:0)

要扩展上述Rob和Paras的响应,尝试连接到Cloud on MQ时2035年响应的两个最常见原因通常是:

  1. 需要启用MQCSP,以便将完整(长)密码传递到队列管理器details available here
  2. 设置适当的授权权限以访问名称不以“ DEV。” details of which are here开头的队列。 (默认情况下,允许访问DEV队列。但是必须为您的应用程序明确授权其他队列

如Rob所建议的那样,队列管理器错误日志应显示详细信息以指示您可能属于哪种情况,并且可以从IBM Cloud用户界面中队列管理器详细信息选项卡中的“日志和诊断”选项卡中下载

关于,马特。