NAME
MQSeries::QueueManager - OO interface to the MQSeries Queue Manager
SYNOPSIS
use MQSeries qw(:functions);
use MQSeries::QueueManager;
#
# Simplest, trivial usage
#
my $qmgr = MQSeries::QueueManager->
new(QueueManager => 'some.queue.manager' ) ||
die("Unable to connect to queue manager\n");
#
# The best way to do error checking. Handle the object
# instantiation and connection to the queue manager independently.
#
my $qmgr = MQSeries::QueueManager->new
(
QueueManager => 'some.queue.manager',
AutoConnect => 0,
) || die "Unable to instantiate MQSeries::QueueManager object\n";
$qmgr->Connect() ||
die("Unable to connect to queue manager\n" .
"CompCode => " . $qmgr->CompCode() . "\n" .
"Reason => " . $qmgr->Reason() .
" (", MQReasonToText($qmgr->Reason()) . ")\n");
#
# Advanced usage. Enable the connection timeout, and connection
# retry logic.
#
my $qmgr = MQSeries::QueueManager->new
(
QueueManager => 'some.queue.manager',
AutoConnect => 0,
ConnectTimeout => 120,
RetryCount => 60,
RetrySleep => 10,
) || die "Unable to instantiate MQSeries::QueueManager object\n";
$qmgr->Connect() ||
die("Unable to connect to queue manager\n" .
"CompCode => " . $qmgr->CompCode() . "\n" .
"Reason => " . $qmgr->Reason() .
" (", MQReasonToText($qmgr->Reason()) . ")\n";
#
# Avoid a channel table file or MQSERVER variable and specify
# the client connect options directly.
#
my $qmgr = MQSeries::QueueManager->new
(
QueueManager => 'some.queue.manager',
ClientConn => { 'ChannelName' => 'FOO',
'TransportType' => 'TCP', # Default
'ConnectionName' => "hostname(1414)",
'MaxMsgLength' => 16 * 1024 * 1024,
},
) || die("Unable to connect to queue manager\n");
#
# Put a message under syncpoint, then commit/backout (in most cases,
# a Put is done using an MQSeries::Queue object instead)
#
my $msg = MQSeries::Message->new(Data => $msg_data);
$qmgr->Put1(Message => $msg,
Queue => 'SOME.QUEUE.NAME',
Sync => 1,
);
if (some_other_work_succeeds()) {
$qmgr->Commit();
} else {
$qmgr->Backout();
}
#
# MQ v7: perform multiple asynchronous Put1 operations,
# then check if any of them ran into issues. Asnchronous
# puts can also be performed from a queue objects, and are
# allowed with syncpoint.
#
foreach my $msg_data (@data_to_be_sent) {
my $msg = MQSeries::Message->new(Data => $msg_data);
$qmgr->Put1(Message => $msg,
Queue => 'SOME.QUEUE.NAME',
PutMsgOpts => { Options => (MQSeries::MQPMO_ASYNC_RESPONSE |
MQSeries::MQPMO_FAIL_IF_QUIESCING),
},
);
}
my $status = $qmgr->StatusInfo();
DESCRIPTION
The MQSeries::QueueManager object is an OO mechanism for connecting to an MQSeries queue manager, and/or opening and inquiring a queue manager object.
This module is used together with MQSeries::Queue, MQSeries::Message and MQSeries::Properties, and the other MQSeries::* modules. These objects provide a simpler, higher level interface to the MQI.
This module also provides special support for connect timeouts (for interrupting MQCONNX() calls that may hang forever), as well as connect retry logic, which will retry failed MQCONNX() calls for a specific list of reason codes.
See the "Special Considerations" section for a discussion of these advanced, but powerful, features.
METHODS
new
The constructor takes a hash as an argument, with the following keys:
Key Value
=== =====
QueueManager String
Carp CODE reference
AutoConnect Boolean
AutoCommit Boolean
ConnectTimeout Numeric
ConnectTimeoutSignal String
GetConvert CODE reference
PutConvert CODE reference
RetrySleep Numeric
RetryCount Numeric
RetryReasons HASH Reference
CompCode Reference to Scalar Variable
Reason Reference to Scalar Variable
- QueueManager
-
This is simply the name of the Queue Manager to which to connect. This is passed directly to the MQCONNX() call as-is.
Normally, this is simply the name of the queue manager to which you wish to connect, but if the "default" queue manager is to be used, then this can either be the empty string "", or simply omitted entirely.
- Carp
-
This key specifies a code reference to a routine to replace all of the carp() calls in the API, allowing the user of the API to trap and handle all of the error message generated internally, or simply redirect how they get logged.
For example, one might want everything to be logged via syslog:
sub MyLogger { my ($message) = @_; foreach my $line (split(/\n+/, $message)) { syslog("err", $line); } }
Then, one tells the object to use this routine:
my $qmgr = MQSeries::QueueManager->new ( QueueManager => 'some.queue.manager', Carp => \&MyLogger, ) || die("Unable to connect to queue manager.\n");
The default, as one might guess, is Carp::carp();
- AutoConnect
-
This is an optional parameter that defaults to true. If the value of this argument is false, then the constructor will not automatically call the
Connect()
method, allowing the developer to call it explicitly, and thus independently error check object instantiation and the connection to the queue manager. See the section on Error Handling in Special Considerations. - AutoCommit
-
If the value of this argument is true, then pending transactions will be committed during object destruction. If it is false, then pending transactions will be backed out before disconnecting from the queue manager during object destruction.
See the section on "AutoCommit" in "Special Considerations".
- ClientConn
-
For client connections, the connection details must be provided somehow. By default, the client channel table file (AMQCLCHL.TAB) or MQSERVER environment variable is used. This optional parameter allows you to specify the details in your code (possibly read from some sort of configuration file or directory service).
The
ClientConn
parameter is a hash reference of which theChannelName
,ConnectionName
andMaxMsgLength
are most relevant. See the description of theMQCD
parameter structure in the Application Programming Reference guide for details on the other fields. - SSLConfig
-
For client connections using SSL, the SSL key repository must be specified. Than can be done usign the
MQSSLKEYR
environment variable, but also using theMQSCO
data structured specified on the MQCONNX. TheSSLConfig
parameters provides a way to specify the key repositority, and overrides theMQSSLKEYR
environment variable. The example below shows how it can be used:my $qmgr = MQSeries::QueueManager-> new(QueueManager => 'some.queue.manager', SSLConfig => { 'KeyRepository' => '/var/mqm/ssl/key' }, );
The
SSLConfig
option is usually combined with theClientConn
parameter documented above. - SecurityParms
-
In MQ v6 and above, security parameters can be specified. The example below shows how it can be used:
my $qmgr = MQSeries::QueueManager-> new(QueueManager => 'some.queue.manager', SecurityParms => { 'AuthenticationType' => MQSeries::MQZAT_INITIAL_CONTEXT, 'CSPUserId' => $userid, 'CSPPassword' => $passwd, }, );
By default, no authentication takes place, and channel security exits can be used.
The
SecurityParms
parameter is a hash reference with membersAuthenticationType
,CSPUserid
andCSPPassword
. See the description of theMQCSP
parameter structure in the Application Programming Reference guide for details on the other fields. - ConnectTimeout
-
If this value is given, it must be a positive integer. This is the time, in seconds, in which an MQCONNX() must complete before the MQI call will be interrupted. The default value is zero, which means the MQCONNX() call will not be interrupted.
There are outage scenarios, in the experience of the author, where the MQCONNX() call will block indefinitely and never return. This happens when a queue manager is "hung", and completely unresponsive, in some cases.
This feature should be used with caution, since it is implemented using a SIGALRM handler, and the alarm() system call. See the section on "Connection Timeouts" in "Special Considerations".
Attempts to use this feature on unsupported platforms that do not support signals will generate a warning, and be silently ignored.
- ConnectTimeoutSignal
-
By default, the ConnectTimeout mechanism is implemented using a signal handler for SIGUSR1, but the signal used to interrupt the MQCONNX() call can be customized using this attribute.
The signal handler installed by this API is done using local(), so the effects of the handler will only override the applications handler during the call to MQCONNX().
The string used for this attribute should be the short hand name of the signal, for example, to set the signal to SIGUSR2:
my $qmgr = MQSeries::QueueManager->new ( QueueManager => 'FOO', ConnectTimeout => 300, ConnectTimeoutSignal => 'USR2', ) || die;
- RetryCount
-
This is an integer value, and specifies the maximum number of times to retry the connection, before failing. The default is 0.
- RetrySleep
-
This is an integer value, and specified the number of seconds to sleep between retries. The maximum timeout for an outage is the product of the RetrySleep and RetryCount parameters. The default is 0.
- PutConvert, GetConvert
-
These are CODE references to subroutines which are used to convert the data in a MQSeries::Message object prior to passing it to the MQPUT MQI call, or convert the data retreived from the queue by the MQGET MQI call before inserting it into a MQSeries::Message object.
These must be CODE references, or the new() constructor will fail. A properly written conversion routine will be passed a single scalar value and return a single scalar value. In the event of an error, the conversion routine should return 'undef'.
The example shown in the synopsis shows how one might use a pair of home grown encryption and decryption subroutines to keep data in clear text in core, but encrypted in the contents of the message on the queue. This is probably not the most hi-tech way to encrypt MQSeries data, of course.
The MQSeries::Message::Storable class provides an example of how to subclass MQSeries::Message to have this type of conversion handled transparently, in the class definition.
- CompCode, Reason
-
When the constructor encounters an error, it returns nothing, and you can not make method calls off of a non-existent object. Thus, you do not have access to the CompCode() and Reason() method calls. If you want to extract these values, you will have to pass a scalar reference value to the constructor, for example:
my $CompCode = MQSeries::MQCC_FAILED; my $Reason = MQSeries::MQRC_UNEXPECTED_ERROR; my $qmgr = MQSeries::QueueManager->new ( QueueManager => 'some.queue.manager', CompCode => \$CompCode, Reason => \$Reason, ) || die "Unable to connect to QueueManager: CompCode => $CompCode, Reason => $Reason\n";
But, this is ugly (authors' opinion, but then, we get to write the docs, too). Use the
AutoConnect
option instead to separatenew
andConnect
. - RetryCount
-
The call to MQCONNX() (implemented via the Connect() method), can be told to retry the failure for a specific list of reason codes. This functionality is only enabled if the RetryCount is non-zero. By default, this value is zero, and thus retries are disabled.
- RetrySleep
-
This argument is the amount of time, in seconds, to sleep between subsequent retry attempts.
- RetryReasons
-
This argument is either an ARRAY or HASH reference indicating the specific reason code for which retries will be attempted. If given as an ARRAY, the elements are simply the reason codes, and if given as a HASH, then the keys are the reason codes (and the values ignored).
Connect
This method takes no arguments, and merely calls MQCONNX() to connect to the queue manager. The various options are all set via the MQSeries::QueueManager constructor (see above).
This method is called automatically by the constructor, unless the AutoConnect
argument is specified and set to false.
Note that this is a new method as of the 1.06 release, and is provided to enable more fine grained error checking. See the ERROR HANDLING section.
Disconnect
This methodtakes no arguments, and merely calls MQDISC() to disconnect from the queue manager.
It is important to note that normally, this method need not be called, since it is implicitly called via the object destructor. If the Disconnect() call errors need to be handled, then it can be done explicitly. See the ERROR HANDLING section.
Backout
This method takes no arguments, and merely calls MQBACK. It returns true on success, and false on failure.
Commit
This method takes no arguments, and merely calls MQCMIT. It returns true on success, and false on failure.
Put1
This method wraps the MQPUT1 call. The arguments are a hash, with the following key/value pairs (required keys are marked with a '*'):
Key Value
=== =====
Message* MQSeries::Message object
Queue String, or ARRAY reference (distribution list)
QueueManager String
ObjDesc HASH reference
PutMsgOpts HASH Reference
PutMsgRecs ARRAY Reference
Sync Boolean
PutConvert CODE reference
Properties HASH Reference or MQSeries::Properties object
The return value is true or false, depending on the success of the underlying MQPUT1() call. If the operation fails, then the Reason() and CompCode() methods will return the appropriate error codes, if the error was an MQSeries error.
If a PutConvert() method failed before the actual MQPUT1() function was called, then the Reason() code will be MQRC_UNEXPECTED_ERROR, and the PutConvertReason() will be true. All of the PutConvert() methods supplied with the various MQSeries::Message subclasses in this distribution will generate some form of error via carp (or the Carp attribute of the objects, if overridden).
- Message
-
This argument is the message to be placed onto the queue. The value must be an MQSeries::Message object.
- Queue
-
This is the queue, or list of queue if using a distribution list, to which to put the message. If it is a single queue, then this value is a string, naming the queue. If it is a distribution list, then this value is an ARRAY reference, listing the target queues. There are three ways to specify the list.
The list may be a simple array of strings:
$qmgr->Put1( Message => $message, Queue => [qw( QUEUE1 QUEUE2 QUEUE3 )], )
or, it can be an array of arrays, each one specifying the queue and queue manager name of the target queue:
$qmgr->Put1( Message => $message, Queue => [ [qw( QUEUE1 QM1 )], [qw( QUEUE2 QM2 )], [qw( QUEUE3 QM3 )], ], )
or finally, it can be an array of hash references, each naming the queue and queue manager:
$qmgr->Put1( Message => $message, Queue => [ { ObjectName => 'QUEUE1', ObjectQMgrName => 'QM1', }, { ObjectName => 'QUEUE2', ObjectQMgrName => 'QM2', }, { ObjectName => 'QUEUE3', ObjectQMgrName => 'QM3', }, ], )
In the latter two cases, the queue manager names are optional. Which method to use is largely a choice of style.
- QueueManager
-
Note that this key is only relevant when not using distribution lists. This identifies the queue manager of the target queue, to which the message is being written. This is an optional key.
- ObjDesc
-
The entire ObjDesc structure passed to the underlying MQPUT1() call can be specified via this key. In this case, the Queue and/or QueueManager are simply ignored. Use of this key would be considered somewhat non-conventional, as the OO API is attempting to hide the complexity of these underlying data structures.
However, this allows the developer access to the entire ObjDesc, if necessary.
- PutMsgOpts
-
This argument forces the developer to specify the complete PutMsgOpts structure, and will override the use of convenience flags, such as Sync. Similar to the use of ObjDesc, this is non-conventional, but provided to allow access to the complete API, if necessary.
- PutMsgRecs
-
This argument is relevant only when using distribution lists.
The value is an ARRAY reference, specifying the put message records for the individual queues in the distribution list. Normally, these are specified as part of the PutMsgOpts, but this API attempts to hide the complexity of the PutMsgOpts structure from the user.
When using distribution lists, PutMsgRecs are often necessary to control how the MsgId, CorrelId, and three other specific fields in the MsgDesc are handled.
For details, see the MQPUT() and MQPUT1() documentation in MQSeries(3).
- Sync
-
This is a flag to indicate that the Syncpoint option is to be used, and the message(s) not committed to the queue until an MQBACK or MQCOMM call is made. These are both wrapped with the Backout() and Commit() methods respectively.
The value is simply interpreted as true or false.
- PutConvert
-
See the new() constuctor documentation for the verbose details. This can be specified for just the Put1() method in the event that a converted message format needs to be put to a queue on a MQSeries::QueueManager object for which default conversion routines have not been installed.
If you have a QueueManager for which all of the Queue use the same message formats, then you can simply specify the PutConvert and GetConvert CODE references once, when the MQSeries::QueueManager object is instantiated. Alternately, you may be specifying the conversion routined for only a few specific queues. In the latter case, it is entirely possible that you will need to specify PutConvert when performing an MQPUT1 MQI call via the Put1() method.
- Properties
-
This parameter is only supported if the module has been compiled with the MQ v7 libraries. It allows properties to be specified with the message. This can be used for selectors or for publish/subscribe.
The Properties parameter can be a hash reference or an MQSeries::Properties object. If it is a hash reference, it can be specified in two ways: as key/value pairs, or with property options.
Specifying the proeprties as key/value pairs is straightforward:
Properties => { 'perl.MQSeries.label' => 'important', 'perl.MQSeries.customer' => 'BigCompany', }
In this case, the property values are specified to MQ as strings, which is usually the correct thing to do. However, property options can be specified if so desired:
Properties => { 'perl.MQSeries.label' => 'important', 'perl.MQSeries.price' => { Type => MQSeries::MQTYPE_FLOAT64, Value => '8.99', }, 'perl.MQSeries.count' => { Type => MQSeries::MQTYPE_INT32, Value => 12, }, }
In addition to Name and Value, you can also specify Encoding and CCSID.
StatusInfo
This method returns status information and is only supported if the module has been compiled for MQ v7. It returns information on previous asynchronous put operations, which can be queue manager Put1 operations or queue Put operations.
The StatusInfo method takes no parameters and returns a hash reference matching the MQSTS data structure. (See the Application Programming Reference for details, or run Data::Dumper on the return value.)
CompCode
This method returns the MQI Completion Code for the most recent MQI call attempted.
Reason
This method returns the MQI Reason Code for the most recent MQI call attempted.
PutConvertReason
This method returns a true of false value, indicating if a PutConvert method failed or not. Similar to the MQRC reason codes, false indicates success, and true indicates some form of error. If there was no PutConvert method called, this will always return false.
Reasons
This method call returns an array reference, and each member of the array is a Response Record returned as a possible side effect of calling a Put1() method to put a message to a distribution list.
The individual records are hash references, with two keys: CompCode and Reason. Each provides the specific CompCode and Reason associated with the put of the message to each individual queue in the distribution list, respectively.
Open
This method takes two optional (but typically not necessary) arguments, and calls MQOPEN() on the Queue Manager, in order to enable the Inquire method. The arguments are a has, with the following keys:
Key Value
=== =====
Options MQOPEN 'Options' Values
ObjDesc HASH reference (MQOD structure)
The Options default to MQOO_INQUIRE|MQOO_FAIL_IS_QUIESCING, which is usually correct. Note that you can not call MQSET() on a queue manager, so MQOO_SET is meaningless, as are most of the other options. Advanced users can set this as they see fit.
The ObjDesc argument is also not terribly interesting, as you most of the values have reasonable defaults for a queue manager. Again, the API supports advanced users, so you can set this as you see fit. The keys of the ObjDesc hash are the fields in the MQOD structure.
This method returns a true of false values depending on its success or failure. Investigate the CompCode() and Reason() for MQSeries-specific error codes.
Close
This method takes no arguments, and merely calls MQCLOSE() to close the actual queue manager object. This is meaningful only if the queue manager has been Open()ed for use by Inquire().
It is important to note that normally, this method need not be called, since it is implicitly called via the object destructor, if necessary. If the Close() call errors need to be handled, then it can be done explicitly. See the ERROR HANDLING section.
Inquire
This method is an interface to the MQINQ() API call, however, it takes more convenient, human-readable strings in place of the C macros for the selectors, as well as supports more readable strings for some of the data values as well.
For example, to query the Platform and DeadLetterQName of a queue manager:
my %qmgrattr = $qmgr->Inquire( qw(Platform DeadLetterQName) );
The argument to this method is a list of "selectors", or QueueManager attributes, to be queried. The following table shows the complete set of possible keys, and their underlying C macro.
Note that this list is all-inclusive, and that many of these are not supported on some of the MQSeries releases or platforms. Consult the IBM documentation for such details.
Key Macro
=== =====
AccountingConnOverride MQIA_ACCOUNTING_CONN_OVERRIDE,
AccountingInterval MQIA_ACCOUNTING_INTERVAL,
ActivityRecording MQIA_ACTIVITY_RECORDING,
AlterationDate MQCA_ALTERATION_DATE,
AlterationTime MQCA_ALTERATION_TIME,
AdoptNewMCACheck MQIA_ADOPTNEWMCA_CHECK,
AdoptNewMCAType MQIA_ADOPTNEWMCA_TYPE,
AlterationTime MQCA_ALTERATION_TIME,
AuthorityEvent MQIA_AUTHORITY_EVENT,
BridgeEvent MQIA_BRIDGE_EVENT,
ChannelAutoDef MQIA_CHANNEL_AUTO_DEF,
ChannelAutoDefEvent MQIA_CHANNEL_AUTO_DEF_EVENT,
ChannelAutoDefExit MQCA_CHANNEL_AUTO_DEF_EXIT,
ChannelEvent MQIA_CHANNEL_EVENT,
ChannelInitiatorControl MQIA_CHINIT_CONTROL,
ChannelMonitoring MQIA_MONITORING_CHANNEL,
ChannelStatistics MQIA_STATISTICS_CHANNEL,
ChinitAdapters MQIA_CHINIT_ADAPTERS,
ChinitDispatchers MQIA_CHINIT_DISPATCHERS,
ChinitServiceParm MQCA_CHINIT_SERVICE_PARM,
ChinitTraceAutoStart MQIA_CHINIT_TRACE_AUTO_START,
ChinitTraceTableSize MQIA_CHINIT_TRACE_TABLE_SIZE,
ClusterSenderMonitoringDefault MQIA_MONITORING_AUTO_CLUSSDR,
ClusterSenderStatistics MQIA_STATISTICS_AUTO_CLUSSDR,
ClusterWorkLoadData MQCA_CLUSTER_WORKLOAD_DATA,
ClusterWorkLoadExit MQCA_CLUSTER_WORKLOAD_EXIT,
ClusterWorkLoadLength MQIA_CLUSTER_WORKLOAD_LENGTH,
CLWLMRUChannels MQIA_CLWL_MRU_CHANNELS,
CLWLUseQ MQIA_CLWL_USEQ,
CodedCharSetId MQIA_CODED_CHAR_SET_ID,
CommandEvent MQIA_COMMAND_EVENT,
CommandInputQName MQCA_COMMAND_INPUT_Q_NAME,
CommandLevel MQIA_COMMAND_LEVEL,
CommandServerControl MQIA_CMD_SERVER_CONTROL,
ConfigurationEvent MQIA_CONFIGURATION_EVENT,
CPILevel MQIA_CPI_LEVEL,
CreationDate MQCA_CREATION_DATE,
CreationTime MQCA_CREATION_TIME,
DeadLetterQName MQCA_DEAD_LETTER_Q_NAME,
DefXmitQName MQCA_DEF_XMIT_Q_NAME,
DistLists MQIA_DIST_LISTS,
DNSGroup MQCA_DNS_GROUP,
DNSWLM MQIA_DNS_WLM,
ExpiryInterval MQIA_EXPIRY_INTERVAL,
IGQUserId MQCA_IGQ_USER_ID,
IGQPutAuthority MQIA_IGQ_PUT_AUTHORITY,
InhibitEvent MQIA_INHIBIT_EVENT,
IntraGroupQueueing MQIA_INTRA_GROUP_QUEUING,
IPAddressVersion MQIA_IP_ADDRESS_VERSION,
ListenerTimer MQIA_LISTENER_TIMER,
LocalEvent MQIA_LOCAL_EVENT,
LoggerEvent MQIA_LOGGER_EVENT,
LUGroupName MQCA_LU_GROUP_NAME,
LUName MQCA_LU_NAME,
LU62ARMSuffix MQCA_LU62_ARM_SUFFIX,
LU62Channels MQIA_LU62_CHANNELS,
MaxActiveChannels MQIA_ACTIVE_CHANNELS,
MaxChannels MQIA_MAX_CHANNELS,
MaxHandles MQIA_MAX_HANDLES,
MaxMsgLength MQIA_MAX_MSG_LENGTH,
MaxPriority MQIA_MAX_PRIORITY,
MaxPropertiesLength MQIA_MAX_PROPERTIES_LENGTH,
MaxUncommittedMsgs MQIA_MAX_UNCOMMITTED_MSGS,
MQIAccounting MQIA_ACCOUNTING_MQI,
MQIStatistics MQIA_STATISTICS_MQI,
MsgMarkBrowseInterval MQIA_MSG_MARK_BROWSE_INTERVAL,
OutboundPortMax MQIA_OUTBOUND_PORT_MAX,
OutboundPortMin MQIA_OUTBOUND_PORT_MIN,
Parent MQCA_PARENT,
PerformanceEvent MQIA_PERFORMANCE_EVENT,
Platform MQIA_PLATFORM,
PubSubMaxMsgRetryCount MQIA_PUBSUB_MAXMSG_RETRY_COUNT,
PubSubMode MQIA_PUBSUB_MODE,
PubSubNPInputMsg MQIA_PUBSUB_NP_MSG,
PubSubNPResponse MQIA_PUBSUB_NP_RESP,
PubSubSyncPoint MQIA_PUBSUB_SYNC_PT,
QMgrDesc MQCA_Q_MGR_DESC,
QMgrIdentifier MQCA_Q_MGR_IDENTIFIER,
QMgrName MQCA_Q_MGR_NAME,
QSharingGroupName MQCA_QSG_NAME,
QueueAccounting MQIA_ACCOUNTING_Q,
QueueMonitoring MQIA_MONITORING_Q,
QueueStatistics MQIA_STATISTICS_Q,
ReceiveTimeout MQIA_RECEIVE_TIMEOUT,
ReceiveTimeoutMin MQIA_RECEIVE_TIMEOUT_MIN,
ReceiveTimeoutType MQIA_RECEIVE_TIMEOUT_TYPE,
RemoteEvent MQIA_REMOTE_EVENT,
RepositoryName MQCA_REPOSITORY_NAME,
RepositoryNamelist MQCA_REPOSITORY_NAMELIST,
SecurityCase MQIA_SECURITY_CASE,
SharedQQMgrName MQIA_SHARED_Q_Q_MGR_NAME,
SSLCRLNamelist MQCA_SSL_CRL_NAMELIST,
SSLCryptoHardware MQCA_SSL_CRYPTO_HARDWARE,
SSLEvent MQIA_SSL_EVENT,
SSLFipsRequired MQIA_SSL_FIPS_REQUIRED,
SSLKeyRepository MQCA_SSL_KEY_REPOSITORY,
SSLKeyResetCount MQIA_SSL_RESET_COUNT,
SSLTasks MQIA_SSL_TASKS,
StartStopEvent MQIA_START_STOP_EVENT,
StatisticsInterval MQIA_STATISTICS_INTERVAL,
SyncPoint MQIA_SYNCPOINT,
TCPChannels MQIA_TCP_CHANNELS,
TCPKeepAlive MQIA_TCP_KEEP_ALIVE,
TCPStackType MQIA_TCP_STACK_TYPE,
TCPName MQCA_TCP_NAME,
TraceRouteRecording MQIA_TRACE_ROUTE_RECORDING,
TreeLifeTime MQIA_TREE_LIFE_TIME,
TriggerInterval MQIA_TRIGGER_INTERVAL,
The return value of this method is a hash, whose keys are those given as arguments, and whose values are the queried queue manager attributes. In almost all cases, the values are left unmolested, but in the following case, the values are mapped to more readable strings.
- Platform (integer)
-
Key Macro === ===== MVS MQPL_MVS NSK MQPL_NSK OS2 MQPL_OS2 OS400 MQPL_OS400 UNIX MQPL_UNIX Win16 MQPL_WINDOWS Win32 MQPL_WINDOWS_NT
ObjDesc
This method can be used to query the ObjDesc data structure. If no argument is given, then the ObjDesc hash reference is returned. If a single argument is given, then this is interpreted as a specific key, and the value of that key in the ObjDesc hash is returned.
NOTE: This method is meaningless unless the queue manager has been MQOPEN()ed via the Open() method.
Special Considerations
AutoCommit
Normally, when you have pending transactions (i.e. MQPUT() and/or MQGET() calls with syncpoint), they will be automatically committed when MQDISC() is called. The MQSeries::QueueManager object destructor, in an attempt to make things easy for the programmer, automatically calls MQDISC() for you. The result is that transactions will be automatically committed when the application exits in any way that allows the object destruction to occur.
This behavior is somewhat counter intuitive, as you would expect transactions to be backed out unless you explicitly say otherwise (i.e. call MQCMIT(), or in this context, the Commit() method call).
As of the 1.12 release of the MQSeries Perl API, this behavior is under the control of the developer. The AutoCommit argument to the object constructor is a Boolean value that specifies whether AutoCommit is on or off. If enabled, then a pending transaction will be committed before disconnecting. If disabled, then the transaction will be backed out, and only if the backout succeeds will we cleanly disconnect.
NOTE: The default behavior was backwards compatible in the 1.12 release, meaning that AutoCommit is enabled by default. However, if you do not specify the AutoCommit behavior explicitly, then the automatic commit of a pending transaction will generate a warning when the object is destroyed. This is because we (the MQSeries Perl API authors) feel that depending on this functionality is dangerous.
ANOTHER NOTE: The default behavior did change with the 1.13 release, and AutoCommit now defaults to 0, not 1, making the intuitive behavior the default.
Connection Timeout Support
There are known outage scenarios wherein the queue manager will be in a "hung" state, where it is entirely unresponsive, but still up and running. Attempts to connect to such a queue manager can block indefinetely, with the MQCONNX() call never returning, until the queue manager is shutdown and restarted. Normally, applications can not trap this error, since they will be stuck in the MQCONNX() call, forever.
By setting the ConnectTimeout argument to the MQSeries::QueueManager constructor, a time limit on MQCONNX() can be imposed, and applications will be able to detect this situation, and take action, if so desired.
This functionality is implemented by forking a child process, which sleeps for the duration of the ConnectTimeout, and then sends a signal to the parent to interrupt the MQCONNX() call. If the MQCONNX() call succeeds before the timeout is reached, then the parent kill the child with the same signal.
By default, SIGUSR1 is used, and the handlers are installed locally, so there should be no conflict with any signal handlers installed by the application, unless you really need your own SIGUSR1 to be enabled during the MQCONNX() call. You can customize the signal used via the ConnectTimeoutSignal argument.
If the timeout occurs, it will be considered a retryable error. (See the next section).
NOTE: This functionality is only supported on platforms that support fork(), and signals, of course. Win32 is not supported, since it does not support sending signals to other processes.
Connection Retry Support
Normally, when MQCONNX() fails, the method that called it (Connect() or new()) also fails. It is possible to have the Connect() method retry the MQCONNX() call for a specific set of reason codes.
By default, the retry logic is disabled, but it can be enabled by setting the RetryCount to a non-zero value. The list of reason codes defaults to a few reasonable values, but a list of retryable codes can be specified via the RetryReasons argument.
You are probably wondering why this logic is useful for MQCONNX(). The choice of the default RetryReasons is not without its own reason.
Consider an application that loses its connection to its queue manager, and thus crashes and restarts. It may very well attempt to reconnect before the queue manager has recovered, and this support allows the application to retry the connection for a while, until it succeeds.
Alternately, consider an application that is started at boot time, possible in parallel with the queue manager. If the application comes up before the queue manager, the MQCONNX() call will fail. Retrying this initial connection will make the application startup more robust.
This makes it easier to have applications recover from queue manager failures, or that have more robust startup logic, but note that this retry logic only applies to the initial connection. Reconnecting at arbitrary points in the code is far more complex, and it left as a (painful) exercise to the reader.
Error Handling
Most methods return a true or false value indicating success of failure, and internally, they will call the Carp subroutine (either Carp::Carp, or something user-defined) with a text message indicating the cause of the failure.
In addition, the most recent MQI Completion and Reason codes will be available via the CompCode() and Reason() methods:
$qmgr->CompCode()
$qmgr->Reason()
When distribution lists are used, then it is possible for a list of reason codes to be returned by the API. Normally, these are buried inside the ObjDesc strucure, but they are also available via the
$qmgr->Reasons()
method. In this case, the $queue->Reason() will always return MQRC_MULTIPLE_REASONS. The return value of the Reasons() method is an array reference, and each array item is a hash reference with two keys: CompCode and Reason. These correspond, respectively, with the CompCode and Reason associated with the individual queues in the distribution list.
For example, the Reason code associated with the 3rd queue in the list would be:
$qmgr->Reasons()->[2]->{Reason}
In the case of the constructor new(), which returns nothing when it fails, these methods are not available. Most applications will not need to handle the specific CompCode and Reason when the instantiation fails, but if necessary, these can be obtained in one of two ways.
The older method, which is supported for backwards compabitility but strongly discouarged, is to pass references to scalar variables to new(). See the new() documentation above for more details.
The newer method would be to explicitly call the Open() method, and error check it yourself. This will mean that the constructor will now fail only if there is an error processing the constructor arguments, as opposed to an error in the MQSeries infrastructure.
Some examples should make this clear.
The simplest way to create an MQSeries::QueueManager object is:
my $qmgr = MQSeries::QueueManager->new
(
QueueManager => 'some.queue.manager',
) || die;
But in this case, the connection to the queue manager could fail, and your application will not be able to determine why.
In order to explicitly have access to the CompCode and Reason one would do the following:
my $qmgr = MQSeries::QueueManager->new
(
QueueManager => 'some.queue.manager',
AutoConnect => 0,
) || die "Unable to instantiate MQSeries::QueueManager object\n";
# Call the Connect method explicitly
unless ( $qmgr->Connect() ) {
die("Connection to queue manager failed\n" .
"CompCode => " . $qmgr->CompCode() . "\n" .
"Reason => " . $qmgr->Reason() . "\n");
}
Conversion Precedence
Once you have read all the MQSeries::* documentation, you might be confused as to how the various PutConvert/GetConvert method arguments and constructor arguments interact with the MQSeries::Message PutConvert() and GetConvert() methods.
The following is the precedence of the various places you can specify a PutConvert or GetConvert subroutine, from highest to lowest:
[A] Put(), Get(), and Put1() method arguments
[B] MQSeries::Message PutConvert() and GetConvert() methods
[C] MQSeries::Queue object defaults (set as arguments to new())
[C] MQSeries::QueueManager object defaults (set as arguments to new())
The cleanest way to code these is probably (and here your mileage will vary wildly with your tastes) to implement a subclass of MQSeries::Message which provides the appropriate GetConvert() and PutConvert() methods, one seperate class for each type of data conversion which is necessary.
Then the conversion happens "under the covers" when message objects of that class are put to or gotten from a queue.
SEE ALSO
MQSeries(3), MQSeries::Queue(3), MQSeries::Message(3), MQSeries::Properties(3)