c++makefileibm-mq

MQRC_Q_MGR_NAME_ERROR


Recently I have been working on a solution that has an integration with MQ Series, and I cannot understand what is going wrong with my solution. Basically, I try to connect with MQ Server in a Mainframe via MQCONNX API but receive the error 2058.

Here is main code:

#include <iostream>
#include <cstring>
#include <cmqc.h>
#include <cmqxc.h>

int main(int argc, char** argv) 
{
    if (argc != 6) {
        std::cerr << "Wrong parameters" << std::endl;
        return -1;
    }

    char* queue_manager_name = argv[1]; // maq
    char* channel_name       = argv[2]; // MQCanal
    char* connection_name    = argv[3]; // MQConexion
    char* transport_type     = argv[4]; // MQTransport

    std::cout << "Trying connection with parameters:\n";
    std::cout << "\tQueue Manager Name (maq)         :" << queue_manager_name << std::endl;
    std::cout << "\tChannel Name       (MQCanal)     :" << channel_name << std::endl;
    std::cout << "\tConnection Name    (MQConexion)  :" << connection_name << std::endl;
    std::cout << "\tTransport Type     (MQTransporte):" << transport_type << std::endl;

    // connection
    MQCD connection_description = { MQCD_CLIENT_CONN_DEFAULT };
    strncpy(connection_description.ChannelName, channel_name, MQ_CHANNEL_NAME_LENGTH);
    strncpy(connection_description.ConnectionName, connection_name, MQ_CONN_NAME_LENGTH);
    strncpy(connection_description.QMgrName, queue_manager_name, MQ_Q_MGR_NAME_LENGTH);
    
    if (strcmp(transport_type, "TCP") == 0) {
        connection_description.TransportType = MQXPT_TCP;
    } else if (strcmp(transport_type, "UDP") == 0) {
        connection_description.TransportType = MQXPT_UDP;
    } else if (strcmp(transport_type, "LU62") == 0) {
        connection_description.TransportType = MQXPT_LU62;
    } else {
        std::cerr << "Invalid transport type, valids are TCP | UDP | LU62" << std::endl;
        return -1;
    }

    MQHCONN conn_handle;
    MQLONG comp_code;
    MQLONG reason;
    MQCNO  connection Options = { MQCNO_DEFAULT };
    connection_options.ClientConnPtr = &connection_description;
    connection_options.Version = MQCNO_VERSION_2;

    MQCONNX(queue_manager_name, &connection Options, &conn_handle, &comp_code, &reason);

    if (comp_code == MQCC_FAILED) {
        std::cerr << "Error to connect against MQ - reason code: " << reason << std::endl;
        return -1;
    }

    MQDISC(&conn_handle, &comp_code, &reason);

    return 0;
}

This small program always get 2058 indicating that Queue Manager Name is wrong or not exists. But in fact, there are other applications implemented in other languages (Java, for example) connecting with MQ Server and using the same parameters.

Environment

This application runs on Solaris 11, and even that I am using C API, my compiler is g++ (gcc), and below is my makefile:

CXX = g++
CXXFLAGS = -std=c++98 -pedantic -Wall -Wextra -Wunused-parameter -Wwrite-strings -g -fpermissive -I/usr/include -I/opt/mqm/inc
MQM_LIB = /opt/mqm/lib64
LDFLAGS = -lrt -L$(MQM_LIB) -lmqm
SRCS = src/main.cpp
OBJS = $(SRCS:.cpp=.o)
DIST_FOLDER = dist
TARGET = $(DIST_FOLDER)/mq
RUNTIME_FOLDER = runtime

all: pre-build $(TARGET) copy_runtime

$(TARGET): $(OBJS)
    $(CXX) -o $@ $^ $(LDFLAGS)

src/%.o: src/%.cpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

pre-build:
    @mkdir -p $(DIST_FOLDER)

clean:
    @rm -rf $(DIST_FOLDER)
    @rm -f $(OBJS) $(TARGET)

copy_runtime:
    @cp $(TARGET) runtime/.

I cannot understand what is the problem. Appreciate any help.


Solution

  • In order to connect to a queue manager on another machine you must use a client connection.

    Please add the following line of code prior to your MQCONNX call.

    connection_options.Options |= MQCNO_CLIENT_BINDING;
    

    Alternatively, but not necessary on modern versions of MQ because of the above, link with mqic library.

    Or alternatively make no change to code at all and set environment variable MQ_CONNECT_TYPE to CLIENT.