MQのclient接続

## 環境

キューマネジャー名：LONDON
キュー名：LON
サーバ接続チャネル名：LONDON.CHANNEL

### 何度かエラーが出ました。

理由：権限付与やチャネル認証を理解していなかったため

以下の対応を実施しました。


### キューマネジャーへの権限追加
※今回は+allで付与しているが、きちんと考慮すべき。
```
 /opt/mqm/bin/setmqaut -m LONDON -t qmgr -p 接続ユーザ名 +all
```

### キューへの権限追加
※今回は+allで付与しているが、きちんと考慮すべき。
```
/opt/mqm/bin/setmqaut -m LONDON -n LON -t queue -p 接続ユーザ名 +all
```

## 以下のソースコードを使ってMQに接続してみました。

### 以下のjarファイルを読み込んでいます。
com.ibm.mq.allclient-9.0.4.0.jar
javax.jms-api-2.0.1.jar


### expire設定を入れているので、500秒後にデータはなくなります。
### WMQConstants.JMS_IBM_MQMD_EXPIRY,5000

```java

// SCCSID "@(#) MQMBID sn=p800-004-151022.DE su=_8QwZKXivEeWg74sVC8pxOw pn=MQJavaSamples/jms/simple/SimpleMQMDWrite.java"
/*
 *   <copyright 
 *   notice="lm-source-program" 
 *   pids="5724-H72,5655-R36,5655-L82,5724-L26," 
 *   years="2008,2012" 
 *   crc="862997680" > 
 *   Licensed Materials - Property of IBM  
 *    
 *   5724-H72,5655-R36,5655-L82,5724-L26, 
 *    
 *   (C) Copyright IBM Corp. 2008, 2012 All Rights Reserved.  
 *    
 *   US Government Users Restricted Rights - Use, duplication or  
 *   disclosure restricted by GSA ADP Schedule Contract with  
 *   IBM Corp.  
 *   </copyright> 
 */

package simple;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsDestination;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;

/**
 * A simple application that demonstrates how a JMS application may write MQ Message Descriptor
 * (MQMD) fields. No messages are received.
 * 
 * Application makes use of fixed literals, any customisations will require re-compilation of this
 * source file.
 * 
 * Notes:
 * 
 * API type: IBM JMS API (v1.1, unified domain)
 * 
 * Messaging domain: Point-to-point
 * 
 * Provider type: WebSphere MQ
 * 
 * Connection mode: Client connection
 * 
 * JNDI in use: No
 * 
 * Queue manager level assumed: v7 or above
 * 
 */
public class SimpleMQMDWrite {

  /*
   * The following note is based on MQMD_VERSION_2. For information about newer fields introduced by
   * a newer version of the MQMD structure, refer to the WebSphere MQ documentation.
   * 
   * Message context: Certain fields in MQMD contain the message context. There are two types of
   * message context -- identity context and origin context. Setting a MQMD field that contains the
   * message context requires the current user to have appropriate WebSphere MQ authority. For the
   * information about Message context, refer to the WebSphere MQ documentation.
   * 
   * Following fields can be set without setting the message context:
   * 
   * CodedCharSetId, CorrelId, Encoding, Expiry, Feedback, Format, GroupId, MsgFlags, MsgId,
   * MsgSeqNumber, MsgType, Offset, OriginalLength, Persistence, Priority, ReplyToQ, ReplyToQMgr,
   * Report.
   * 
   * Following fields require the identity context authority or, the superset, origin context
   * authority: AccountingTo, ApplIdentityData, UserIdentifier.
   * 
   * Following fields require the origin context authority: ApplOriginData, PutApplName,
   * PutApplType, PutDate, PutTime.
   * 
   * The identity context can be set in JMS by the following:
   * 
   * ((JmsDestination) destination).setIntProperty(WMQConstants.WMQ_MQMD_MESSAGE_CONTEXT,
   * WMQConstants.WMQ_MDCTX_SET_ALL_CONTEXT);
   * 
   * The origin context can be set in JMS by the following:
   * 
   * ((JmsDestination) destination).setIntProperty(WMQConstants.WMQ_MQMD_MESSAGE_CONTEXT,
   * WMQConstants.WMQ_MDCTX_SET_ALL_CONTEXT);
   * 
   * The identity context must be set in the above manner by setting a property on the destination
   * before the corresponding (identified) Producer object is instantiated.
   */

  // System exit status value (assume unset value to be 1)
  private static int status = 1;

  /**
   * Main method
   * 
   * @param args
   */
  public static void main(String[] args) {

    // Variables
    Connection connection = null;
    Session session = null;
    Destination destination = null;
    MessageProducer producer = 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, "192.168.2.170");
      cf.setIntProperty(WMQConstants.WMQ_PORT, 1414);
      cf.setStringProperty(WMQConstants.WMQ_CHANNEL, "LONDON.CHANNEL");
      cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
      cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "LONDON");

      // Insist on queue manager level to be v7 or above
      cf.setStringProperty(WMQConstants.WMQ_PROVIDER_VERSION, "7.0.0.0");
     

      // Create JMS objects
      connection = cf.createConnection();
      session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      destination = session.createQueue("queue:///LON");

      // Enable write of MQMD fields. See documentation for further details.
      ((JmsDestination) destination).setBooleanProperty(WMQConstants.WMQ_MQMD_WRITE_ENABLED, true);

      // Set message context, if needed. See comment at the top.

      // Create a producer
      producer = session.createProducer(destination);

      // Create a message
      long uniqueNumber = System.currentTimeMillis() % 1000;
      TextMessage message = session
          .createTextMessage("SimpleMQMDWrite: Your lucky number today is " + uniqueNumber);

      // Generate a custom message id
      byte[] customMessageId = new byte[24];
      for (int i = 0; i < 24; i++) {
        // Hex-string 010203040506070801020304050607080102030405060708
        customMessageId[i] = (byte) ((i % 8) + 1);
      }

      // Write to MQMD.MsgId via JMS_IBM_MQMD_MSGID message property
      message.setObjectProperty(WMQConstants.JMS_IBM_MQMD_MSGID, customMessageId);
      message.setIntProperty(WMQConstants.JMS_IBM_MQMD_EXPIRY,5000);
      message.setIntProperty(WMQConstants.JMS_IBM_MQMD_PRIORITY,8);
      // Start the connection
      connection.start();

      // And, send the message
      producer.send(message);
      System.out.println("Sent message:\n" + message);

      recordSuccess();
    }
    catch (JMSException jmsex) {
      recordFailure(jmsex);
    }
    finally {
      if (producer != null) {
        try {
          producer.close();
        }
        catch (JMSException jmsex) {
          System.out.println("Producer could not be closed.");
          recordFailure(jmsex);
        }
      }

      if (session != null) {
        try {
          session.close();
        }
        catch (JMSException jmsex) {
          System.out.println("Session could not be closed.");
          recordFailure(jmsex);
        }
      }

      if (connection != null) {
        try {
          connection.close();
        }
        catch (JMSException jmsex) {
          System.out.println("Connection could not be closed.");
          recordFailure(jmsex);
        }
      }
    }
    System.exit(status);
    return;
  } // end main()

  /**
   * 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;
  }

  /**
   * 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;
  }

}
```

無事に接続できました。

## 接続後の確認
```

bash-4.2$ /opt/mqm/samp/bin/amqsbcg LON LONDON

AMQSBCG0 - starts here
**********************

 MQOPEN - 'LON'


 MQGET of message number 1, CompCode:0 Reason:0
****Message descriptor****

  StrucId  : 'MD  '  Version : 2
  Report   : 0  MsgType : 8
  Expiry   : 4561  Feedback : 0
  Encoding : 273  CodedCharSetId : 1208
  Format : 'MQHRF2  '
  Priority : 8  Persistence : 1
  MsgId : X'010203040506070801020304050607080102030405060708'
  CorrelId : X'000000000000000000000000000000000000000000000000'
  BackoutCount : 0
  ReplyToQ       : '                                                '
  ReplyToQMgr    : 'LONDON                                          '
  ** Identity Context
  UserIdentifier : 'kenke       '
  AccountingToken :
   X'0000000000000000000000000000000000000000000000000000000000000000'
  ApplIdentityData : '                                '
  ** Origin Context
  PutApplType    : '28'
  PutApplName    : 'simple.SimpleMQMDWrite      '
  PutDate  : '20240915'    PutTime  : '05452163'
  ApplOriginData : '    '

  GroupId : X'000000000000000000000000000000000000000000000000'
  MsgSeqNumber   : '1'
  Offset         : '0'
  MsgFlags       : '0'
  OriginalLength : '-1'

****   Message      ****

 length - 215 of 215 bytes

00000000:  5246 4820 0000 0002 0000 00A8 0000 0111           'RFH ............'
00000010:  0000 04B8 4D51 5354 5220 2020 0000 0000           '....MQSTR   ....'
00000020:  0000 04B8 0000 0020 3C6D 6364 3E3C 4D73           '....... <mcd><Ms'
00000030:  643E 6A6D 735F 7465 7874 3C2F 4D73 643E           'd>jms_text</Msd>'
00000040:  3C2F 6D63 643E 2020 0000 005C 3C6A 6D73           '</mcd>  ...\<jms'
00000050:  3E3C 4473 743E 7175 6575 653A 2F2F 2F4C           '><Dst>queue:///L'
00000060:  4F4E 3F6D 6457 7269 7465 456E 6162 6C65           'ON?mdWriteEnable'
00000070:  643D 7472 7565 3C2F 4473 743E 3C54 6D73           'd=true</Dst><Tms'
00000080:  3E31 3732 3633 3739 3132 3135 3533 3C2F           '>1726379121553</'
00000090:  546D 733E 3C44 6C76 3E32 3C2F 446C 763E           'Tms><Dlv>2</Dlv>'
000000A0:  3C2F 6A6D 733E 2020 5369 6D70 6C65 4D51           '</jms>  SimpleMQ'
000000B0:  4D44 5772 6974 653A 2059 6F75 7220 6C75           'MDWrite: Your lu'
000000C0:  636B 7920 6E75 6D62 6572 2074 6F64 6179           'cky number today'
000000D0:  2069 7320 3534 31                                 ' is 541         '



 No more messages
 MQCLOSE
 MQDISC
-bash-4.2$


```