Connecting to MQ using XMS .Net without MQ client - c#

I am trying to connect to MQ using XMS .Net. The MQ is currently setup on the server and using IBM.WMQ I am able to connect to it. Now I want to explore the IBM XMS as it supports API so in future we can try connecting to MQ from .net full-framework or .net core clients.
Spent 2 days over the web but not able to find a full sample where this is implemented. I also don't want to install the MQ client on my local machine. Is there a way to do this? Are there any good articles available for the same?

Following link provides an overview of XMS.NET
http://www-01.ibm.com/support/docview.wss?uid=swg27024064
IBM MQ Redistributable package can be used to develop MQ .NET applications without installing the Client.You will have to use MQ v9.0.5 or above to use XMS.NET client.You can download the latest redistributable package from the following link
9.1.0 IBM MQ C and .NET redistributable client for Windows x64
If you have MQ client install then there are samples located at "MQ_INSTALL_PATH\Tools\dotnet\samples\cs\xms\simple\wmq" and following link provides a brief description about the samples
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.0.0/com.ibm.mq.xms.doc/xms_csamp.html
Following is the code sample to get a message asynchronously using Message listeners.
/// <summary>
/// Setup connection to MQ queue manager using XMS .NET
/// </summary>
private void ibmmqSetupConnection()
{
XMSFactoryFactory factoryFactory;
IConnectionFactory cf;
IDestination destination;
IMessageConsumer consumerAsync;
MessageListener messageListener;
// Get an instance of factory.
factoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
// Create WMQ Connection Factory.
cf = factoryFactory.CreateConnectionFactory();
// Set the properties
cf.SetStringProperty(XMSC.WMQ_HOST_NAME, "host.ibm.com");
cf.SetIntProperty(XMSC.WMQ_PORT, 1414);
cf.SetStringProperty(XMSC.WMQ_CHANNEL, "QM.SVRCONN");
cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "QM1");
cf.SetStringProperty(XMSC.USERID, "myuserid");
cf.SetStringProperty(XMSC.PASSWORD, "passw0rd");
// Create connection.
connectionWMQ = cf.CreateConnection();
// Create session with client acknowledge so that we can acknowledge
// only if message is sent to Azure Service Bus queue
sessionWMQ = connectionWMQ.CreateSession(false, AcknowledgeMode.ClientAcknowledge);
// Create destination
destination = sessionWMQ.CreateQueue("INPUTQ");
// Create consumer
consumerAsync = sessionWMQ.CreateConsumer(destination);
// Setup a message listener and assign it to consumer
messageListener = new MessageListener(OnMessageCallback);
consumerAsync.MessageListener = messageListener;
// Start the connection to receive messages.
connectionWMQ.Start();
// Wait for messages till a key is pressed by user
Console.ReadKey();
// Cleanup
consumerAsync.Close();
destination.Dispose();
sessionWMQ.Dispose();
connectionWMQ.Close();
}

Related

Unable to send a message with AMQP.Lite and IBMMQ 8.0

I'm developing a new service based on our infrastructure that uses IBMMQ 8.0 (I've to admit that I'm not a guru of IBMMQ and I've used it as a simple integration without diving in it's implementation).
I'm trying right now to use It with amqpnetlite (in order to use it with .NET Core).
Till now here's my snippet
Address address = new Address("amqp://10.112.62.102:1414");
Connection connection = new Connection(address);
Session session = new Session(connection);
Message message = new Message("Hello AMQP!");
var sender = new SenderLink(session, "AONMQCOL1", "MQ_TEST");
sender.Send(message);
Console.WriteLine("Sent Hello AMQP!");
I got an exception AmqpException: The transport 'TcpTransport' is closed. when performing the Send. On the connection object I've got IsClosed = false so I think the connection is open.
Just as confirmation, what should I put as "address" and "name" on the SenderLink's constructor?
Thanks
What is the exact version of MQ Server you are running? i.e. issue the dspmqver command.
You need to be at Command Level 801 which was added in Fixack 2 of IBM MQ v8. i.e. IBM MQ v8.0.0.2. See here for more details.
Did you start the AMQP service and then start the channel?
i.e. runmqsc commands:
START SERVICE(SYSTEM.AMQP.SERVICE)
START CHANNEL(SYSTEM.DEF.AMQP)
Finally, are you connecting to the correct port #? The default port # is 5672.

Unable to connect at IBM WebSphere MQ 8.xx

I'm trying to connect to an IBM WebSphere MQ 8.x, but what should be simple as it's with RabbitMQ seems so difficult on IBM world.
I've created a Console Application (.NET Framework), referenced the amqmdnet.dll 8.0.0.10)
and here's my snippet
var connectionName = "X.X.X.X(4418)";
Hashtable properties = new Hashtable();
properties.Add(MQC.CONNECTION_NAME_PROPERTY, connectionName);
properties.Add(MQC.CHANNEL_PROPERTY,"TEST_XXX_RECEIVER");
var mqQMgr = new MQQueueManager("DEFAULT.XXXMQCOL1",properties );
mqQMgr.Connect();
What I got when trying to connect is IBM.WMQ.MQException: 'MQRC_Q_MGR_NAME_ERROR'
For that concern the Queue name I've put the name I found on the node
The Channel property is a channel I've defined in the queue node of websphere
I've tried to telnet on ip:port and it connects
Any suggestion?
UPDATE #1
Even if I do "Start" from context menu, it remains inactive, can this lead to the constructor's hang?
UPDATE #2
I've managed it. I was going wrong on two steps
I have the LISTENER.TCP stopped under the listeners
I was pointing at 4418 which is the Queue Manager port and I had to point at 1414 (Listener.TCP port)
Now I'm able to connect, admin you can close it
You appear to be using sender and/or receiver channels. Use SVRCONN for clients

C# - UnitTest message received through IBM Websphere MQ

I am new to IBM Websphere MQ.
In our projet, I have implemented code to read messages from IBM MQ.
I have installed IBM WebSphere client and I am using references of IBM.XMS and IBM.XMS.Client.WMQ to create the connection and read the message from the queue.
XMSFactoryFactory xff = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
IConnectionFactory cf = xff.CreateConnectionFactory();
I have set the necessary properties like HostName, Channel, Port, QueueManager.
I have created the MessageListener:
MessageListener messageListener = new MessageListener(Method to process the message);
I have assigned listener to consumer:
consumer.MessageListener = messageListener;
I am able to connect to queue manager, read the message and display that message in WPF window.
Now for above code I have to write the UnitTest.
As per my knowledge, in unittest we won't be creating connection and reading from queue so how can I mock above code so that I can pass dummy message and check that.
The XMS API you are calling will actually communicate with a queue manager. So without a queue manager the API's will fail and so will the unit test.

Service Bus 1.1 creating Queue with WindowsAzure.ServiceBus dll

I am preparing to develop application that connects to Azure Service Bus. For development I want use Service Bus 1.1.
I have installed localy Service Bus 1.1 and it works fine when I am connecting with package Service Bus.v1_1 ver. 1.0.5.
But as I want eventually work with Azure I prefer to use package WindowsAzure Service Bus which as I know sholud work with Service Bus 1.1.
But when I want to execute:
namespaceManager.QueueExists(queueName)
with WindowsAzure.ServiceBus ver 3.1.2 package I receive:
'System.ArgumentException' ....
The remote server returned an error: (400) Bad Request. The api-version in the query string is not supported. Either remove it from the Uri or use one of '2012-03,2012-08,2013-04,2013-07'.
Adding ?api_version=2013-07 to Uri does not helps.
However sending message to queue that exists on local SB1.1 works well (Using WindowsAzure.ServiceBys 3.1.2).
So it just applies to connections with NamespaceManager.
Could anyone has any ideas why it does not work ?
The code I use for tests:
var cs ="Endpoint=sb://mylocalmachine/ServiceBusDefaultNamespace/;StsEndpoint=https://mylocalmachine:9355/ServiceBusDefaultNamespace/;RuntimePort=9354;ManagementPort=9355";
var queueName = "AAA";
var namespaceManager = NamespaceManager.CreateFromConnectionString(cs);
var messagingFactory = MessagingFactory.CreateFromConnectionString(cs);
var ver = namespaceManager.GetVersionInfo();
if (namespaceManager.QueueExists(queueName))
{
namespaceManager.DeleteQueue(queueName);
}
namespaceManager.CreateQueue(queueName);
QueueClient client = messagingFactory.CreateQueueClient(queueName);
client.Send(new BrokeredMessage("Hello! " + DateTime.Now));
client = messagingFactory.CreateQueueClient(queueName, ReceiveMode.ReceiveAndDelete);
BrokeredMessage message = client.Receive();
if (message != null)
{
Console.WriteLine(message.GetBody<string>());
}
Console.ReadKey();
To my knowledge the WindowsAzure.ServiceBus package is not compatible with on premises Windows Service Bus. We are stuck with using the old package.
I believe the libraries are source compatible for most things, so when you DO migrate to using Azure service bus instead of on-prem, then it should be as simple as swapping out the package and changing the authentication mechanisms and connection strings and recompiling and testing.

Working against a Secure-Channel with Security-Exit using XMS .NET API

I own the following findings in order to work againts WMQ Secure-Channel:
Defined Secure-Channel in the WMQ farm
Public/Private keys
Unmanaged Security-Exit assembly
My question is how to utilize these resources and interact with a Secure Channel using the XMS API? (Using C#)
This is what I've tried so far, but without success:
private IConnectionFactory CreateConnectionFactory()
{
XMSFactoryFactory factoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
IConnectionFactory connectionFactory = factoryFactory.CreateConnectionFactory();
connectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, _wmqHostName);
connectionFactory.SetIntProperty(XMSC.WMQ_PORT, _wmqPort);
connectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, _wmqChannel);
connectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);
connectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, _wmqQueueManager);
connectionFactory.SetIntProperty(XMSC.WMQ_BROKER_VERSION, 0);
connectionFactory.SetStringProperty(XMSC.WMQ_SECURITY_EXIT, "MySecurityExitName");
return (connectionFactory);
}
I get the following error when calling it:
CWSMQ0006E: An exception was received during the call to the method
ConnectionFactory.CreateConnection: CompCode: 2, Reason: 2195 . During
execution of the specified method an exception was thrown by another
component. See the linked exception for more information.
UPDATE:
I found the following Technote which describes my problem and its possible (not tested) solution:
https://www-304.ibm.com/support/docview.wss?uid=swg1IC82112
Good that you found that Technote. Also make sure that...
If doing mutual authentication (SVRCONN channel is set to SSLCAUTH(REQUIRED)) that the app's personal certificate has a label matching the service account. Example, if the app is running as dotnetacct the label of the personal cert in its keystore would be ibmwebspheremqdotnetacct.
Get the channel running without SSL or an exit first. Then do server-authenticated SSL, then mutually authenticated SSL, then add the exit back in. This isolates problems.
Use the latest WMQ client. I do not mean the latest fix pack for v7.0 or v7.1 but the latest v7.5 (as of this writing) client. Download as SupportPac MQC75. Later clients are compatible with back-level QMgrs and they have more fixes/features.
Install the full client and not just the classes or assemblies you think you need. This gets you all sorts of utilities such as client-side tracing.
Use the amqssslc sample to test your channel and certificates. This is usually at C:\Program Files (x86)\IBM\WebSphere MQ\tools\c\Samples\Bin\amqssslc.exe and is one of the utilities supplied when installing the full client.
Go to the WMQ SupportPacs page and look for MH03 WebSphere MQ SSL Configuration Checker and MO04 WebSphere MQ SSL Wizard. These can help with configuration and problem diagnosis.
I figured-out that you can't use an unmanaged Security Exit assembly with IBM.XMS API (IBM.XMS.dll), and this is what I currently have.
From the XMS docs:
XMSC.WMQ_SECURITY_EXIT
This property is relevant only when an application connects to a queue
manager in managed client mode. Also, only managed exits are
supported.
Eventually, I came up with replacing the usage of the XMS API with the MQ Classes for .NET (Native .NET API of IBM for WMQ) which does support using an unmanaged Security Exit, by setting its MQC.SECURITY_EXIT_PROPERTY property (should be served in the form of a Hashtable entry). To be more specific, this is the assembly: amqmdnet.dll

Categories