Reputation: 7412
I'm tasked with sending a test message to an (as yet) unknown MQ endpoint.
I've stood a trial version of IBM WebSphere MQ (v8.0.0.5) on a server, which I believe is configured correctly.
However, given the code included below I get either the exception:
An unhandled exception of type 'IBM.WMQ.MQException' occurred in amqmdnet.dll
Additional information: 2059
Or if I am on the server itself using localhost
instead of the remote server name, the constructor line hangs.
This is C#:
Hashtable connectionProperties = new Hashtable();
string connectionType = MQC.TRANSPORT_MQSERIES_MANAGED
connectionProperties.Add(MQC.TRANSPORT_PROPERTY, connectionType);
// Set up the rest of the connection properties, based on the
// connection type requested
switch (_connectionType)
{
case MQC.TRANSPORT_MQSERIES_BINDINGS:
break;
case MQC.TRANSPORT_MQSERIES_CLIENT:
case MQC.TRANSPORT_MQSERIES_XACLIENT:
case MQC.TRANSPORT_MQSERIES_MANAGED:
connectionProperties.Add(MQC.HOST_NAME_PROPERTY, "server.com");
connectionProperties.Add(MQC.CHANNEL_PROPERTY, "SYSTEM.DEF.CLNTCONN");
break;
}
MQQueueManager qMgr = new MQQueueManager("test", connectionProperties);
MqClientTest mqClientTest=new MqClientTest("TEST_QM","localhost", "SYSTEM.DEF.CLNTCONN");
Is there anything we're missing in this?
Update 1:
In the amqerr01.log
file in the errors
folder, we now have the text:
AMQ6183: An internal WebSphere MQ error has occurred.
Update 2:
The "internal WebSphere MQ error" was likely due to my probing the 1414 port to see if the port was "up" and listening. Seems it was and it obviously didn't like me doing that.
Update 3:
@Roger suggested I use 127.0.0.1
and capitals, which I've now applied - and changed the example above to reflect.
@JoshMc kindly pointed to a second AMQERR01.LOG file within the Queue Manager folder. I now get the error:
14/11/2017 15:35:08 - Process(336.6) User(xxxx) Program(amqrmppa.exe) Host(xxxx) Installation(xxxx) VRMF(8.0.0.5) QMgr(TEST_QM) AMQ9519: Channel 'SYSTEM.DEF.CLNTCONN' not found.
EXPLANATION: The requested operation failed because the program could not find a definition of channel 'SYSTEM.DEF.CLNTCONN'.
TEST_QM
is my Queue Manager, with the default (?) channel SYSTEM.DEF.CLNTCONN
Upvotes: 1
Views: 4047
Reputation: 10642
With IBM MQ there are always a pair of channels that work together. For example if one MQ Queue Manager needs to send to message to another queue manager it would normally have a SDR
(Sender) channel defined, which would point to a RCVR
(Receiver) channel with the same name on the other queue manager.
For a MQ client connection the client application side of the channel is called a MQCD
, and the MQ Queue Manager side is a SVRCONN
(Server Connection) channel. The client side MQCD
can be specified in a few different ways. The way you are demonstrating in the example you posted is programmatically specifying the MQCD
information (channel name, hostname, etc).
An alternate way to specify the information is by pointing to a CCDT
(Client Channel Definition Table) which is commonly referred to as a Channel Table, this is where a CLNTCONN
channel would be used, since you are not using a Channel table I'll move on to why you are getting an error, but at the end of this answer I'll provide more details on Channel Tables.
In summary your application should not be specifying a CLNTCONN
channel as the MQC.CHANNEL_PROPERTY
it should be pointing to a SVRCONN
channel.
Two things to note:
SYSTEM.*
channels for this purpose (for example SYSTEM.DEF.SVRCONN
), you should define a new channel for your application to use. The default channels are meant to hold parameters that you want to be the defaults when creating a new channel of the same type.CHLAUTH
rules enabled by default which will block access to the SYSTEM.*
channels.If you want to define a SVRCONN
channel using the command line program runmqsc
on Windows run the following on a CMD prompt:
echo DEFINE CHL(TEST_QM_CHANNEL1) CHLTYPE(SVRCONN)|runmqsc TEST_QM
Few more details about Channel Tables:
Prior to MQ v8 the only supported method to generate a Channel Table was by defining CLNTCONN
channels on a queue manager which creates a file called AMQCLCHL.TAB
under the queue manager name folder in a directory called @ipcc
. The reason a queue manager comes with a channel called SYSTEM.DEF.CLNTCONN
is to provide the default values when you create a new CLNTCONN
channel. With v8 and later you can create the channel table using only the runmqsc -n
mode, this will directly edit the channel table vs needing to create a CLNTCONN
channel on a queue manager. The MQ Client for v8 and later now comes with a client version of runmqsc
that can be used to create and alter channel tables.
An application can point to the channel table file in a few different ways, a common way is by setting two environment variables (MQCHLLIB
and MQCHLTAB
). The app then does not specify channel name, host name, etc in the program, it only needs to specify the name of the queue manager to connect to.
The order and where MQ looks for connection information is documented at the IBM v7.5 (or later) Knowledge Center page "Connecting IBM WebSphere MQ MQI client applications to queue managers". Note this link is for MQI clients, but the same basic order applies to .NET clients as well.
Upvotes: 1
Reputation: 7456
localhost
Try using 127.0.0.1 rather than localhost.
"rx" and "swift_test_tx"
Since you are new to MQ, it is time for you to read up on MQ Best Practices. One item is that it is NOT a good idea to use lowercase characters for MQ objects names. i.e. queues, channels, etc... MQ will always fold to uppercase any names that are not in quotes. So, it is just better to uppercase the names to begin with (less problems in the future).
Next, did you open port 1414 in your firewall? If not, then open the port for both TCP & UDP.
Here's an example of a C# program to put a message to a queue in a remote queue manager:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using IBM.WMQ;
/// <summary> Program Name
/// MQTest51
///
/// Description
/// This C# class will connect to a remote queue manager
/// and put a message to a queue under a managed .NET environment.
///
/// Sample Command Line Parameters
/// -h 127.0.0.1 -p 1414 -c TEST.CHL -m MQWT1 -q TEST.Q1
///
/// </summary>
namespace MQTest51
{
class MQTest51
{
private Hashtable inParms = null;
private Hashtable qMgrProp = null;
private System.String qManager;
private System.String outputQName;
/*
* The constructor
*/
public MQTest51()
: base()
{
}
/// <summary> Make sure the required parameters are present.</summary>
/// <returns> true/false
/// </returns>
private bool allParamsPresent()
{
bool b = inParms.ContainsKey("-h") && inParms.ContainsKey("-p") &&
inParms.ContainsKey("-c") && inParms.ContainsKey("-m") &&
inParms.ContainsKey("-q");
if (b)
{
try
{
System.Int32.Parse((System.String)inParms["-p"]);
}
catch (System.FormatException e)
{
b = false;
}
}
return b;
}
/// <summary> Extract the command-line parameters and initialize the MQ variables.</summary>
/// <param name="args">
/// </param>
/// <throws> IllegalArgumentException </throws>
private void init(System.String[] args)
{
inParms = Hashtable.Synchronized(new Hashtable());
if (args.Length > 0 && (args.Length % 2) == 0)
{
for (int i = 0; i < args.Length; i += 2)
{
inParms[args[i]] = args[i + 1];
}
}
else
{
throw new System.ArgumentException();
}
if (allParamsPresent())
{
qManager = ((System.String)inParms["-m"]);
outputQName = ((System.String)inParms["-q"]);
qMgrProp = new Hashtable();
qMgrProp.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
qMgrProp.Add(MQC.HOST_NAME_PROPERTY, ((System.String)inParms["-h"]));
qMgrProp.Add(MQC.CHANNEL_PROPERTY, ((System.String)inParms["-c"]));
try
{
qMgrProp.Add(MQC.PORT_PROPERTY, System.Int32.Parse((System.String)inParms["-p"]));
}
catch (System.FormatException e)
{
qMgrProp.Add(MQC.PORT_PROPERTY, 1414);
}
if (inParms.ContainsKey("-u"))
qMgrProp.Add(MQC.USER_ID_PROPERTY, ((System.String)inParms["-u"]));
if (inParms.ContainsKey("-x"))
qMgrProp.Add(MQC.PASSWORD_PROPERTY, ((System.String)inParms["-x"]));
if ( (inParms.ContainsKey("-u")) && (inParms.ContainsKey("-x")) )
qMgrProp.Add(MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
}
else
{
throw new System.ArgumentException();
}
}
/// <summary> Connect, open queue, write a message, close queue and disconnect.
///
/// </summary>
/// <throws> MQException </throws>
private void testSend()
{
System.String line;
int openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
try
{
MQQueueManager _qMgr = new MQQueueManager(qManager, qMgrProp);
System.Console.Out.WriteLine("MQTest51 successfully connected to " + qManager);
MQQueue queue = _qMgr.AccessQueue(outputQName, openOptions, null, null, null); // no alternate user id
System.Console.Out.WriteLine("MQTest51 successfully opened " + outputQName);
MQPutMessageOptions pmo = new MQPutMessageOptions();
// Define a simple MQ message, and write some text in UTF format..
MQMessage sendmsg = new MQMessage();
sendmsg.Format = MQC.MQFMT_STRING;
sendmsg.Feedback = MQC.MQFB_NONE;
sendmsg.MessageType = MQC.MQMT_DATAGRAM;
line = "This is a test message embedded in the MQTest51 program.";
sendmsg.MessageId = MQC.MQMI_NONE;
sendmsg.CorrelationId = MQC.MQCI_NONE;
sendmsg.WriteString(line);
// put the message on the queue
queue.Put(sendmsg, pmo);
System.Console.Out.WriteLine("Message Data>>>" + line);
queue.Close();
System.Console.Out.WriteLine("MQTest51 closed: " + outputQName);
_qMgr.Disconnect();
System.Console.Out.WriteLine("MQTest51 disconnected from " + qManager);
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("MQTest51 cc=" + mqex.CompletionCode + " : rc=" + mqex.ReasonCode);
}
catch (System.IO.IOException ioex)
{
System.Console.Out.WriteLine("MQTest51 ioex=" + ioex);
}
}
/// <summary> main line</summary>
/// <param name="args">
/// </param>
// [STAThread]
public static void Main(System.String[] args)
{
MQTest51 write = new MQTest51();
try
{
write.init(args);
write.testSend();
}
catch (System.ArgumentException e)
{
System.Console.Out.WriteLine("Usage: MQTest51 -h host -p port -c channel -m QueueManagerName -q QueueName [-u userID] [-x passwd]");
System.Environment.Exit(1);
}
catch (MQException e)
{
System.Console.Out.WriteLine(e);
System.Environment.Exit(1);
}
System.Environment.Exit(0);
}
}
}
Upvotes: 0