This file documents the changes to each and every release of the MQSeries
perl API, going back as far as the 1.02 release.
Jeff Dunn contributed patches to the IMBS Bridge Header class
MQSeries::Message::IIH that make it work on both little-endian and
big-endian platforms. By default, the module assumes client and server will
run on platforms with the same endian-ness; this can be overridden if this
is not the case.
When a message has format MQFMT_NONE; sender and receiver run on platforms
with different endian-ness; and the receiver specifies Get-Message Option
MQGMO_CONVERT; then MQ returns completion code MQCC_WARNING and reason code
MQRC_FORMAT_ERROR.
The MQSeries::Queue Get()
method used to treat this as an
error. In this particular case (Format MQFMT_NONE), the warning can be
ignored. The method now treats this as a succesful read.
The MQGET, MQPUT and MQPUT1 functions now use MQMD version 2 and MQGMO
version2 by default; MQPUT and MQPUT1 now use MQPMO version2 by default if
a distribution list is specified. Applications using message grouping,
segmentation, or distribution lists no longer have to specify the MsgDesc,
GetMsgOpts or PutMsgOpts version explicitly.
It is still possible to set a higher MQMD, MQGMO or MQPMO version
explicitly. Note that this change will break use of older (pre-5.0) queue
managers, but as these are over 5 years out of date, this should not
matter.
Howard Muten noted that specifiying a too-short correlation id on MQPUT
resulted in garbage bytes written to MQ. This turned out to be a generic
problem, where user-supplied data that was too short was copied in with
whatever memory contenst was following. This has been fixed in the typemap
code.
Brian Bumpass contributed XS code to add support for the SSLConfig options
to the MQCONNX
call, as well as support for the additional ClientConn parameters
introduced in WMQ 5.3. These options have also been added to the
MQSeries::QueueManager class. Use of these options obviously requires a WMQ
5.3 client with the optional SSL support installed and configured.
The MQSeries::Command class now supports connecting directly to the
mainframe (z/OS) using client connections. As the default syncpoint
behavior on MQPUT for this platform is different, this module now
explicitly specifies MQPMO_NO_SYNCPOINT when writing a message.
On the mainframe (z/OS), WMQ 5.3 supports queue-sharing groups. The
MQSeries::Command::MQSC classes have been extended to support the following
features:
-
Add the 'Shared' option to the queue DefinitionType parameter values
-
In
CreateObject(),
do not alter the object but delete and
recreate it when either the QSharingGroupDisposition or CFStruct attributes
has changed.
Mike Surikov contributed further patches to support reading and writing of
channel table files, including fields new with version 7 of this file (WMQ
5.3). Generation and parsing of the older versions is still supported.
James FitzGibbon contributed some configure options for Makefile.PL to pick
the right MQ libraries on AIX.
The deprecated option NoAutoOpen for the MQSeries::Queue constructor new
is no longer supported.
The deprecated MQSeries::Queue methods Commit
, Backout
and
Pending
are no longer supported. Obviously, these methods are still supported on
the MQSeries::QueueManager object.
The deprecated option NoAutoConnect for the MQSeries::QueueManager constructor new
is no longer supported.
Minor fixes for the InquireClusterQueueManager
command; add support for RefreshCluster
command. At this time, support for
ResetCluster
, SuspendQueueManagerCluster
and
ResumeQueueManagerCluster
is not planned (patches are welcome).
T. Rob Wyatt requested the ability to write to a caller-supplied filehandle
in the MQSeries::Config::ChannelTable writeFile
method; this allows him to supply channel tables from a CGI script without
having to create temporary files.
Support for this is now provided using the new FileHandle
parameter to the writeFile
method.
Mike Surikov contributed patches to support reading and writing of version
6 client channel table files. Previous releases did not handle all fields.
The default version of files written is now version 6, though generation
and parsing of the older version format is still supported.
A new class to support trigger monitor messages; this allows you to write a
trigger monitor in perl.
On Linux and HP-UX, the MQ libraries are different for single- and
multi-threaded programs. The makefile now tries to pick the right libraries
based on the 'usethread' parameter in Config.pm.
Mike Surikov supplied a patch that makes the 'Escape' method of
MQSeries::Command work. This is used when sending MQSC commands using PCF.
The deprecated parameters NoAutoConnect for
MQSeries::QueueManager
and NoAutoOpen for MQSeries::Queue
will generate a run-time warning whether -w is enabled or not. In the next
release, the warning becomes a fatal error.
The deprecated MQSeries::Queue
methods Commit
, Backout
and
Pending
will generate a run-time warning whether -w is enabled or not. In the next
release, the warning becomes a fatal error.
This release drops support for MQSeries 5.0, Solaris 2.5.1 and IRIX. We
have not made any changes to the code that should affect these platforms
and releases, but no longer have hese host types around. If you care about
these platforms, we'll be happy to merge patches to keep them working.
In previous releases, specifying the PutMsgOpts
with the Put
method or the GetMsgOpts
with the Get
method of
MQSeries::Queue
meant that Sync
, Wait
and Convert
parameters were ignored.
This has now changed: the Sync
, Wait
and Convert
parameters will be honored and be combined with the get/put options
specified with the PutMsgOpts
or GetMsgOpts
parameters.
The Get
method Wait
and Convert
parameters will override the
GetMsgOpts
options flag.
The Get
and Put
method Sync
paramater will check the
GetMsgOpts
or PutMsgOpts
options flag for compatibility. If a coflicting syncpoint option is already
set, a fatal error will be raised. If no conflicting option is set (this
means the options flkag either has no syncpoint flag set at all, or has the
requested flag set already), the requested Sync
paramater will be added to the options flag.
This means the following will now work:
my $result = $request_queue->
Get('Message' => $get_message,
'GetMsgOpts' =>
{
'Options' => (MQSeries::MQGMO_SYNCPOINT_IF_PERSISTENT |
MQSeries::MQGMO_FAIL_IF_QUIESCING),
},
'Wait' => '30s',
);
In the past, this would cause the Wait
flag to be silently ignored.
This incompatible API change may break your code. As it significantly
enhances the safety of your code, this is deemed a price worth paying.
WebSphere MQ 5.3 on z/OS can generate configuration change events that
cannot be read on Unix and NT queue managers - distributed queue managers
are not able to convert PCF version2 messages. The
MQSeries::Message::ConfigEvent class can be used to process such messages -
highly useful to create an audit log.
A new class to support IMS Bridge Header (IIH) messages. This is due to
Nathan Dupra of Xerox USA. This class is based on reverse engineering and
somewhat experimental - feedback on functionality or the API is welcome.
A number of minor changes have been made to support MQSeries::Command with
the 5.3 release (now branded WebSphere MQ) on z/OS. Note that PTF UQ68236
is required - the MQSC output of ``Display Queue'' is invalid without that
PTF, leading to errors with the InquireQueue
method.
-
Support for AuthInfo objects in
MQSeries::Command
, mostly through changes in the MQSeries::Command::MQSC::*
tables.
-
Support for CFStruct (Coupling Facility Application Structure) objects in
MQSeries::Command
, mostly through changes in the
MQSeries::Command::MQSC::*
tables.
-
Support for the new Channel attributes in
MQSeries::Command
, mostly through changes in the MQSeries::Command::MQSC::*
tables. The new attributes are BatchHeartBeat
, KeepAliveInterval
,
LocalAddress
, SSLCipherSpec
, SSLClientAuth
and
SSLPeerName
.
-
Support for the new QueueManager attributes in
MQSeries::Command
, mostly through changes in the MQSeries::Command::MQSC::*
tables. The new attributes are ConfigurationEvent
, ExpiryInterval
,
SSLKeyRepository
, SSLCRLNamelist
, SSLCryptoHardware
and
SSLTasks
.
-
Support for the new Queue attributes in
MQSeries::Command
, mostly through changes in the MQSeries::Command::MQSC::*
tables. The new attribute is PageSetId
.
-
Support for the new Namelist attributes in
MQSeries::Command
, mostly through changes in the MQSeries::Command::MQSC::*
tables. The new attribute is NamelistType
.
The MQSeries::Command
constructor now accepts a CommandQueue
parameter. This allows you to open an arbitrary queue with arbitary
options, then use it so send commands.
In addition, a new MsgDesc
method for MQSeries::Command
can be used to fine-tune the message descriptor for outgoing commands.
These new features can be used to open an arbitarry queue and override
message persistence, as some users requested; internally, we sue it to set
the accounting options on outgoing messages, which are then archived by the
WMQ 5.3 configuration events on z/OS.
Mike Surikov pointed out more bugs in the decoding of MQSC result messages
in MQSeries::Command
. I've added more fixes...
The parameters to the major methods of the MQSeries::QueueManager
class (new
, Connect
, Close) are now enforced. Specifying invalid parameter names will lead to a fatal
run-time error.
The parameters to the major methods of the MQSeries::Queue
class (new
, Open
, Get
) are now enforced. Specifying invalid parameter names will lead to a fatal
run-time error.
The Get
method of MQSeries::Queue
has a new Convert
option. This is true by default, but can be set to false if conversion is
not required. This is useful when manually converting messages, e.g. WMQ
5.3 configuration events.
The deprecated parameters NoAutoConnect for
MQSeries::QueueManager
and NoAutoOpen for MQSeries::Queue
will generate a warning if -w is enabled. In the next release, the warning
becomes mandatory.
The deprecated MQSeries::Queue
methods Commit
, Backout
and
Pending
will generate a warning if -w is enabled. In the next release, the warning
becomes mandatory.
A number of minor changes have been made to support the 5.3 release (now
branded WebSphere MQ).
-
The format of AMQERR01.LOG files has changed: the record separator can now
contain a filename and line. Update to
MQSeries::ErrorLog::Parser
.
-
The product name in many message in the AMQERR01.LOG file has changed; some
error messages have been added and others have minor changes. Update to
MQSeries::ErrorLog::descriptions.pl
.
-
The format of FDC files has changed: the product name at the start of each
record has changed. Update to
MQSeries::FDC::Parser
, which now supports both the old and the new product name.
-
Support for AuthInfo objects in
MQSeries::Command
, mostly through changes in the MQSeries::Command::PCF::*
tables.
-
Support for the new
InquireQueueStatus
command, mostly through changes in the MQSeries::Command::PCF::*
tables.
-
Support for the new Channel attributes in
MQSeries::Command
, mostly through changes in the MQSeries::Command::PCF::*
tables. The new attributes are BatchHeartBeat
, LocalAddress
, SSLCipherSpec
,
SSLClientAuth
and SSLPeerName
.
-
Support for the new QueueManager attributes in
MQSeries::Command
, mostly through changes in the MQSeries::Command::PCF::*
tables. The new attributes are ConfigurationEvent
, SSLKeyRepository
,
SSLCRLNamelist
and SSLCryptoHardware
.
Jim Wendorf reported that the MQSeries::Config::ChannelTable
file did not reliably read and write channel tables on Windows NT. This was
due to missing binmode()
statements and sort order issues and
has now been fixed.
Edwin Haswell contributed code for improved client vs server API support.
The plain ``use MQSeries;'' code should now work again for client
installations.
The MQSeries::Command
class now supports the InquireQueueStatus
command when using MQSC commands. This works against mainframe queue
managers running MQSeries release 5.2 and up.
The MQSeries module now requires perl5.005. We test internally with both
perl5.005 and perl5.6.
The MQSeries::Command constructor now performs strict parameter name
validation and will throw an exception (using confess())
if an
invalid parameter name is passed.
This has the potential of breaking existing, but buggy, code. Similar
changes will be made to many of the other classes and methods in upcoming
releases.
Paul Meekin submitted an interesting bug showing we got message retry wrong
when the initial data buffer is too large and message conversion is
required (reason code MQRC_TRUNCATED_MSG_FAILED). Effectively, we were
re-using the MQMD returned after the warning, which caused the requested
coded character set and encoding to be ignored. This is now fixed.
However, this bug also showed that some of the retry logic was
non-functional; the non-working code has now been removed. The retry logic
failed in the following (rare) corner-case:
-
You are getting a string message and requesting conversion
-
The data buffer specified is large enough to hold the message before
conversion
-
The message expands during conversion (e.g., Latin-1 to UTF-8)
-
The data buffer specified is not large enough to hold the message after
conversion
It turns out that in this case (when MQCC_WARNING and
MQRC_CONVERTED_STRING_TOO_BIG is returned) is not retryable. The only thing
the application can do, if the message was read under syncpoint, is to roll
back and try again with a properly sized data buffer.
The MQSeries::Command module will now delay loading for the sub-classes
MQSeries::Command::PCF and MQSeries::Command::MQSC until either one is
actually used. Under most circumstances, this will save a substantial
amount of memory. Apache mod_perl users may want to pre-load the relevant
sub-class as part of their startup script.
Hirosi Taguti noted that the MQCONNX call did not properly support
client-connection options. After he persisted in his bug reports for a
year, we finally fixed it - which required adding some XS code. Note that
the syntax for the ClientConn options may be different than expected, as
the MQCNO 'versions' and 'Options' flags must also be accomodated:
$HConn = MQCONNX($QmgrName,
{ 'ClientConn' => { 'ChannelName' => 'FOO',
'TransportType' => 'TCP',
'ConnectionName' => "hostname(1414)",
},
},
$CompCode,
$Reason);
The MQSeries::QueueManager
class now uses MQCONNX and supports an optional ClientConn
parameter to specify these options.
Various people noted that MQSeries 5.2 CSD03 and CSD04 caused a number of
tests to break. This is because the various header files now provide two
different values for various constants, depending on whether you compile in
32-bit mode or 64-bit mode. As we are not running a full C pre-processor,
that broke the constant parsing.
We now support these changed header files, though we do not yet support the
64-bit client mode on Solaris (patches are welcome).
Jim Hildebrand at MQ Software tried to use the MQSeries::Command suite on
Windows 2000 and discovered that the order in which PCF command options are
specified was dependent on the platform hash key ordering, even though the
PCF command server requires a specific ordering for some keys. The perl
hash key ordering happened to work on Solaris, but broke on Windows 2000
(and possibly other platforms).
Joseph Sacco at Starwood Hotels reported that the MQSeries::Command suite,
when run against a mainframe using MQSC commands, gave annoying errors
messages because the terminating response line on his mainframe queue
manager has a different format from ours.
We now accept both formats. If you run MQSeries::Command against a
mainframe and get error messages like:
Unrecognized MQSC buffer: /T2 CSQMDRTS ' DISPLAY QUEUE' NORMAL COMPLETION
then please get in touch and send us the error message.
Peter Giorgilli reported that we had a bug in the XS code that caused us to
return garbage data when reading zero-length messages. It turns out a
similar issue caused zero-length PCF strings to be misread for responses
from little-endian queue managers (e.g. Linux/ia32 and Windows). These
zero-length string bugs have been corrected throughout all the XS code.
The NoAutoConnect flag for the MQSeries::QueueManager constructor has been
renamed to AutoConnect (with, obviously, reverse meaning of the option
values). The default behavior remains the same and the next few releases
will support the old flag for backwards compatibility.
The NoAutoOpen flag for the MQSeries::Queue constructor has been renamed to
AutoOpen (with, obviously, reverse meaning of the option values). The
default behavior remains the same and the next few releases will support
the old flag for backwards compatibility.
In retrospect, it was probably a mistake to add Commit()
and
Backout()
methods to the MQSeries::Queue class and have them
delegate these calls to the queue manager object. Some developers were
confused by this and thought the scope of transactions was per-queue.
However, it is valid to create an MQSeries::Queue object without creating
an MQSeries::QueueManager object first, and Commit()
and
Backout()
have to be called on something - so it seemed like a
reasonable thing to do.
A new method for MQSeries::Queue, QueueManager(),
can be used
to extract the queue manager object from a queue. The documentation has
been updated to reflect that Commit()
and
Backout()
should be called on the queue manager object, not on
the queue. The queue-level Commit()
and Backout()
methods will be dropped in a future release.
The SYSTEM.DEF.CLNTCONN definition must be present, or the client can get
upset in certain error conditions, so the code now forces this to the front
of the list, even if you don't specify it.
The physical order of the entries, and the order in which the linked list
pointers binds them together, now patches exactly the same pattern as IBM
uses to generate the file on a queue manager. It is very possible that
noone at Hursley will be able to tell one of my files from one of theirs.
;-)
And that's a challenge....
This was one of those 'how did this ever work?' problems. The core was
fatally broken. Fixed.
The extended PCF API to query/alter Unix authorities now supports a thirs
entity type, 'AFS' (PCF macro MQETE_AFS_GROUP). As this requires a modified
command server and custom Object Authority Manager (OAM) only used at
Morgan Stanley, this should not affect anyone else.
The CreateObject method of MQSeries::Command now supports an optional
call-back to perform the comparison of object attributes. This is only
useful in obscure circumstances.
The StorageClass object type (as used on the OS/390 version of MQSeries) is
now supported by the MQSeries::Command class.
In order to add some statistics gathering code to the command API, the
MQSeries::Command::Response objects will not keep the unconverted PCF data
structures in the Buffer attribute of the object, allowing direct
manipulation of the data, of necessary.
We need to be able to measure the absolute size of the original message,
since we are trying to gather metrics on the load placed on MQSeries
systems by administrative tools thatuse this API.
This is one of this ``how did this ever work?'' bugs.
The logic to test the support for fork()
in the current perl
build was wrong. This has been fixed, and the retry logic tested
successfully.
This code is clever, and re-parses mqs.ini whenever it changes so that long
running daemons wil automatically detect new queue manager installation.
However, the method name was incorrect, and this resulted in a fatal
runtime error. Oops.
The MQSeries::Command class now supports MQSeries version 5.2 on the
mainframe. This includes support for the new QSharingGroup,
CouplingFacility, CommandScope and IntraGroupQueueing keywords; and the new
ResetQueueStatistics method, which returns the same results as the Unix
(PCF) version. The new DisplayQueueStatus MQSC command is not yet
supported.
Support for MQSeries 5.2 on Unix has also been tested; however, as this
worked without changes, none were made.
As warned when we deployed 1.12, MQSeries::QueueManager's AutoCommit
functionality is disabled by default now. If you want pending transactions
to be automatically committed when your disconnect, you must set AutoCommit
in your code.
The MQSeries modules were becoming a serious memory hog, largely due to the
import/export of all constants in modules the included MQSeries.
The MQSeries moduly now optionally allows importing just the functions,
then referring to constants using an MQSeries:: prefix. This has been done
throughout the MQSeries library internally, leading to a space saving of
some 3 MB for programs using MQSeries::Command.
This change is fully backwards-compatible. There is no impact on programs
using the MQSeries module, though these can reduce their memory footprint
(if desired) by selectively importing the required MQSeries functions.
The code has always tried to make a missing channel status appear to be a
successful command, and to return the ``ChannelStatus'' value of
``NotFound'', since this is not really an error. Unfortunately, we broke
this when we reorganized the MQSeries::Command code for 1.12.
The CompCode and Reason will now be reset to MQCC_OK and MQRC_NONE, as well
as returning a ChannelStatus of ``NotFound''.
In the NameValueString of the MQRFH message, that is. According to IBM (I
checked), there is nothing in the spec or the code of the pubsub
broker(s)
that will prohibit the user of leading whitespace in
the MQRFH NameValueString, so the perl API needs to be tolerant of the
same.
As this module did not compile, it probably wasn't used by anyone.
The keyword in the hash tables used to map strings to PCF macros had a bug.
Principal was mispelled, causing any query of permissions that involved
principals to fail.
This was guaranteed to impact only MSDW....
These are really hex values, and we were pretending that they were decimal.
This generates warning when the values are used for numerical comparisons.
The CompCode and Reason values are now ``eval''ed as hex, and thus
converted to decimal values.
This method returns either the MQReasonToText value for the commandd reason
code, or the ReasonText returned by MQSC. It wasn't documented. It is now.
You can't pass Force as an object attribute, since it is supported by
ChangeFoo but not by CreateFoo commands, in general. The specification of
Force is not an argument to CreateObject itself, and should not be passed
as a key in the Attrs hash.
The ``Response'' method of the MQSeries::Command class conflicts with the
MQSeries::Command::Response class, and this causes headaches in some code.
The method has been renamed to ``Responses''.
Now, this is obviously a non-backwards compatible change, however, that
method is very, very rarely used, and this will probably affect no existing
code. But, you've been warned.
WARNING: This is a very subtle, but very significant change to the API.
Anyone using transactions should read and understand the implications for
their application.
Normally, when there are pending tranactions due to uncommited
MQPUT()
and/or MQGET()
calls, they will be
implicitly backed out if the application crashes. This is a good thing. If
the application chooses to cleanly exit, and calls MQDISC()
without first calling MQCMIT(),
then the transactions will be
implicitly commited. This is a good thing, when you do it intentionally.
In the MQSeries::QueueManager object destructor, the code does an
MQDISC()
automatically in order to attempt to be a good
citizen and cleanly disconnect from queue manager automatically. However,
if an application has pending tranactions, and it traps a non-MQSeries
related error and dies, object destruction still occurs, and this means
that the pending transactions will be automatically commited, often to the
surprise of the application developer.
This release offers the developer control of this behavior, via the new
AutoCommit argument to the MQSeries::QueueManager constructor. If
AutoCommit is disabled, then the object destructor will call
MQBACK()
before it calls MQDISC(),
if there are
pending transactions (the rest of the code conspires to keep track of this
state information for you automatically, of course).
ANOTHER WARNING: The default behavior is not being changed in 1.12.
AutoCommit will be 1 by default, and transactions will be automatically
commited, in order to be backwards compatible with the current behavior. In
1.13, we will change this, since we feel very strongly that the intuitive
behavior should be the default. If the application does not explicitly
commit transactions, then they will be backed out when we destroy the
MQSeries::QueueManager objects.
This means that applications will NOT be required to explicitly call MQBACK()
(well, the
->Backout() method, that is) in all of their error handling. This is
especially important if you call some other API which itself raises fatal
exceptions, since you won't be required to trap them and take special
action. As of 1.13, we will Do The Right Thing.
Attempts to connect to unhealthy queue managers can often hang
indefinetely, and there is no way for applications to interrupt the
connection, or trap the error. You simply hang until the queue manager (or
the wedged component) is killed.
The new MQSeries::QueueManager support a ConnectTimeout attributes which
puts a time limit on the MQCONN()
call.
The modules now compile and install on OS/390. See the README file for
version details.
A new class under MQSeries::Config, which can be used to parse and query
authority files under Unix. The 'saveauth' program in the 'examples'
directory shows how this can be used to save all object authorities in a
file of 'setmqaut' commands.
Actually, this fixes a pretty serious bug. CreateObject, which is a
wonderfully powerful command, was also rather dangerous, because the author
(er, uh, that would be me -- wpm) got a bit pazy, and just used the PCF
Create commands, with the Replace option. That works fine if you are always
specifying all or most of the attributes you care about. If, however, you
provide a subset of the attributes you care about, the others will get
wiped out, since you are giving a sparse set of attributes to, say,
CreateQueue.
The code will now DTRT and use the Change commands if the object already
exists, and Create if it doesn't. This is far safer, and makes the code
very robust.
If one of the attributes passed in is a single element ARRAY reference, it
would not compare correctly with a real object attribute of only one
element, since the inquiry API will not return it as an ARRAY reference
unless there are two or more entries. A single element ARRAY ref will be
flattened to a scalar to make this comparison correct.
Some vendors impose a limit of 255 stdio files that can be open at the same
time (though the number of open file descriptors can be quite a bit
higher). For an queue manager running really poorly, the number of FDC
files being written may be higher than that, causing perl to die with a
``too many open files'' error. The MQSeries::FDC::Tail class will now close
and re-open files in such circumstances (using a least-recently-used
approach).
The 'Wait' and 'Expiry' parameters for MQSeries::Command, MQSeries::Queue
and MQSeries::PubSub::Command are specified in units of 1/1000 and 1/10 of
a second, making it easy to get the magnitude wrong. These parameters can
now also be specified as symbolic values, e.g. '45s' for 45 seconds and
'2m' for 2 minutes.
NOTE: These symbolic values work at the API top-level, but not when you
manually create a MsgDesc hash. Low-level values must be specified in
numeric form.
See the 1.11 changes notes about PutConvert, roughly a page or so below
this. It was an oversight not to make the analagous changes for GetConvert
as well as PutConvert.
It is now possible to determine if the failure of a Put(),
Put1()
or Get()
method calls was a result of a
failed PutConvert()
or GetConvert()
method, which
is called internally by each of the first 3 methods.
This is important when you want to know if the error was a result of an
improperly formatted message body, or an MQSeries problem.
While some noise gets generated via carp, there was until now no way to
determine this programmatically.
The DeleteQueue command has an undocumented dependency on the order of its
optional attributes. We enhanced the configuration of the PCF attributes
such that we can now specify the order for these parameters. Without this
change, commands that specified the Purge option worked half the time,
since it was just lucky if perl pulled the hash entries out in the right
order.
Now, we force the parameters to be converted into PCF code in the correct
order. Currently, this only applies to the Optional parameters for
DeleteQueue, but if we run into any further undocumented order
dependencies, we can accomodate them easily.
Two new classes under MQSeries::Config, specifically Machine and QMgr,
allow read access to the parsed /var/mqm/mqs.ini and
/var/mqm/qmgrs/*/qm.ini files.
Three new classes under MQSeries::ErrorLog, specifically Tail, Parser, and
Entry, allow parsing and monitoring of errorlog files
(/var/mqm/errors/AMQERR0x.LOG, /var/mqm/qmgrs/*/errors/AMQERR0x.LOG).
Three new classes under MQSeries::FDC, specifically Tail, Parser, and
Entry, allow parsing and monitoring of FDC files (/var/mqm/errors/*.FDC).
A new subclass of MQSeries::Message, which implements parsing of the MQDLH,
has been added to the distribution. This makes it trivial to write dead
letter queue handler applications in perl.
We only error check the return value of the PutConvert()
method is one was actually called. This makes it possible to put empty
messages (where all of the information you care about is in the header, for
example).
This method tries very hard not to alter objects whose attributes are
already correctly set, but the previous version couldn't handle comparing
attributes whose values were lists. For example, if you give more than one
exit to the MsgExit parameter of a channel, then the PCF query will return
a list of values, and this is represented as an ARRAY reference.
The new version will correctly compare the array elements, and thus
correctly determine whether or not the attributes with multiple values are
in fact correct. And yes, order is of course important.
In all of the following modules, the GetConvert()
method will
save the raw buffer, which in gives the developer access to the raw,
unconverted data, via the MQSeries::Message->Buffer() method.
MQSeries::Message::Storable
MQSeries::Message::XML-Dumper
MQSeries::Message::RulesFormat
MQSeries::Message::DeadLetter (new in 1.11 -- see above)
MQSeries::Message::PCF
MQSeries::Command::Response
MQSeries::PubSub::AdminMessage
A similar change was made to MQSeries::Message::Event, in the 1.09 release,
but this has not been done for all of the supported modules in the
distribution, for consistency (and, because the author happened to need
this for MQSeries::Message::Storable).
Previously, the name of the permanent dynamic model queue, and dynamic
queue name to be created, were simply hardcoded in the object constructor
for both of
MQSeries::PubSub::Broker
MQSeries::PubSub::Stream
Both are now configurable via arguments to the constructor.
This one is hard to explain. The code to parse the PCF admin messages for
PubSub wasn't handling multiple subscriber identities correctly. It does
now.
There was a missing else condition to carp about an MQOPEN failure, if the
ReasonCode was not in the list of values to be retried. This causes significant confusion,
since the failure is silent.
Thanks to yet another data length limitation, the string ``INITIALIZING''
is too long for OS/390 to display, so this gets truncated to
``INITIALIZI'', for output of the InquireChannelStatus()
command, only on that platform. The API can parse this correctly now.
The IndexType values weren't properly mapped on either requests or
responses. Now they are.
The HardenGetBackout paremeter was incorrectly encoded in MQSC. It is now.
This is one that came back to haunt me, as I thought I had fixed this way
back in 1.04. If you attempt to create an MQSeries::Message with a
BufferLength of zero, you actually get one with the default value of 32K.
This is bad, if you are writing some code to say, browse a queue and just
get all of the headers, as you end up getting some of the data, too. The
code does the right thing now, and properly accepts a BufferLength of 0.
I added a new key (Clear) to indicate that when replacing a Local queue
with another QType, the Local queue should be cleared before being deleted.
There are also a couple of examples in the SYNOPSIS section, and
documentation for the new method call. This can now be considered
production, and is no longer experimental. The author uses this call almost
exclusively, in new development, for creating objects.
This release compiles on Windows NT 4.0, and has thus far been tested with
ActiveState 5.00503, build 521, with Visual C++ 6.0. Other perl/compiler
combinations will probably follow, but the initial support is all the
author has to test. I've tested it with 5.0 as a client, and 5.1 as both
client and server.
NOTE: (and a WARNING, too). This code determines where your MQSeries
installation is by querying the Windows Registry, using Win32::TieRegistry.
This is done not only at compile time (to find the includes files and
shared libs), but also at run time to determine whether or not to use the
client or server API, automatically.
The retry logic was always there in MQSeries::QueueManager->Connect(),
but now it is much more configurable. You can specify which reasons codes
are worth retrying, rather than depend on a hardcoded (and possibly wrong
or incorrect) list.
MQSeries::Queue->Open() also support retry logic, and the author finds
this very useful for daemons recovering from a previous crash, attempting
to open a queue for exclusive input, and waiting for the previously invoked
agent process to free up the input handle.
The documentation for both modules has a RETRY LOGIC section. See that for
more information, as well as the documentation for the constructors, and
each of the specific methods.
The MQSeries::Command constructor takes additional arguments allowing you
to specify the Model Queue, and DynamicQName used to open the dynamic reply
queue for command messages.
WARNING: This new method, while being Very Cool, is EXPERIMENTAL, and
intentionally not documented, as the API will likely change. It will
probably stabilize in 1.10.
CreateObject is a higher level wrapper function that will only create the
specified object if it doesn't exist, or the specified attributes don't
match. This is a conditional object creation, that will be a noop if the
object is already correctly configured.
A global hash, keyed on the process ID, and the Hconn value, will keep
track of how many MQSeries::QueueManager objects have been instantiated for
a given queue manager connections (since the Hconn values get reused). The
object destructor will now decrement these values, and only the last object
will actually disconnect from the queue manager.
This is actually a significant enhancement, as it was possible to
pre-maturely disconnect from the queue manager when instantiating lots of
objects, all of them specifying the queue manager by name, and thus
internally recreating lots of MQSeries::QueueManager objects. The first one
to get destroyed would wipe out the connection, causing problems for the
others.
The constructor argument QueueManager can now be another
MQSeries::QueueManager argument, and the QueueManager name will be stolne
from that object, and a new one instantiated. This really just allows an
MQSeries::QueueManager object to be passed to the MQSeries::PubSub::Broker
constructor, actually.
The Hobj value returned by MQOPEN()
is only saved in the
object hash when the CompCode is either MQCC_OK or MQCC_WARNING. The value
when there is a failure can be a large, useless negative number, but then
this looks like a true value in perl.
This confuses the subsequent attempts to call ->Open(), which are
supposed to return true if the object is already opened. This was done via:
return 1 is $self->{Hobj};
which will be wrong. This is primarily relevant is you implement any form
of retry logic for failed queue opens.
A new method to return the raw buffer from an MQGET()
call.
This is relevant for classes which use GetConvert()
methods to
translate the raw data into a customized form. If they save the raw buffer
into $self->{Buffer}, then it will be available.
This GetConvert()
method will save the raw buffer, which in
this case gives the developer access to the raw PCF data. The author uses
this to echo the original event, in its unaltered format, to other systems
management packages, afte rhe gets to it first.
This is another relatively minor bug fix release, but since I'm releasing
it internally at MSDW, I'm also releasing it to CPAN as well.
I made a global variable lexically scoped to its file with an erroneous
``my'' keyword. Don't do that. The Event parsing class was totally broken
as a result.
When a command fails, the Reason()
was being set to the last
reason code found in the returned messages, which is always 3008 (command
failed). Now the code will catch the first non-zero return code, and
default to that, and this reason code is usually the one you want.
For example, InquireQueue for a non-existent queue name will now return
2085 (object not found), instead of the generic and uninteresting 3008.
Although I don't recommend using this particular interface, the
constructors for both of these classes allow you to pass scalar references
for the Reason and CompCode, so that the MQCONN()
or
MQOPEN()
errors, if any, can be obtained.
These were only being set if there was an error, and now they are set
regardless. Thus, if you initialize the values to, say
MQRC_UNEXPECTED_ERROR and MQCC_FAILED, they will be left that way.
Note that I highly recommend using the NoAutoConnect and NoAutoOpen
arguments, and then error checking the ->Connect() and ->Open()
methods explicitly. The resulting code is much cleaner, IM!HO.
The various *_FAIL_IF_QUIESCING
options are set everywhere by
default (as the author happens to beleive they should be), except here.
This is fixed.
In order to enable the development of adminstrative tools for
Publish/Subscribe which allow me to age bogus subscriptions (i.e.
subscriptions that point to non-existent queues), I needed to be able to
DeregisterSubscriber as an alternate user ID.
The API was enhanced to expose a bit more of the underlying method calls in
order to make this possible.
In addition, several minor bugs in the Administrative PubSub API were
fixed, making it possible to get at almost all of the metatopic information
easily.
This release is a minor bug fix release, but one of them is significant
enough to justify a public release.
The MQDecodePCF routine didn't properly mortalize the references it
returns. I hate it when that happens. The result was that long-running
applications that used the Command API (or any of the PCF-based formats)
heavily (guess what the author was developing when he discovered this? ;-)
will leak memory heavily. This is fixed.
In addition, the same error was made in the MQSeries::Message::RulesFormat
XS code as well, and that was also fixed.
Note that none of the basic MQI interfaces had any problems at all. There
are now no known memory leaks anywhere in the XS code. We've had long
running perl daemons up for weeks using the basic MQSeries interface, with
no reported issues.
The obnoxious, er, I mean, very important and absolutely essential legal
question about the LICENSE file will be asked only once. When compiling
statically, the Makefile.PL gets run again, and if it blocks on input this
is not only annoying, but it breaks the static compile.
The default Expiry values used in the MQSeries::Command API were incorrect,
having the same value as the WaitInterval. As you probably know, Expiry is
tenths of a second, and Wait is milliseconds. Oops.
This release is the first to make it to CPAN (the Comprehensive Perl
Archive Network), as the primary distribution mechanism, rather than IBM's
proprietary Support Pac web site. In addition, this code is now copyrighted
by MSDW (the author's employer) but released under a license which is based
on the Perl Artistic License.
It is now truly Open Source. Viva the Revolution, baby...
The entire Publish/Subscribe API is new with this release. This includes
the following modules:
- MQSeries::PubSub::Command
-
A base class for all of the Publish/Subscribe commands, this module is not
used directly, but rather one of its two subclasses is.
- MQSeries::PubSub::Broker
-
This subclass of MQSeries::PubSub::Command, and MQSeries::QueueManager,
implements an interface to the Broker-specific Publish/Subscribe commands.
This module also supports an set of ``Extended Commands'', which are higher
level interfaces to the contents of the administrative inforamtion in the
metatopics.
- MQSeries::PubSub::Stream
-
This subclass of MQSeries::PubSub::Command, and MQSeries::Queue, implements
an interface to the Stream-specific Publish/Subscribe commands.
- MQSeries::PubSub::Message
-
This subclass of MQSeries::Message::RulesFormat provides an interface for
creating and parsing MQRFH-formated Publish/Subscribe messages.
- MQSeries::PubSub::AdminMessage
-
This quasi-subclass (not a *true* OO subclass, but who's looking) of
MQSeries::Message::PCF provides an interface to the Publish/Subscribe
administrative messages published in PCF format.
This is a new class which provides a much more generic interface to PCF
messages. Prior to this release, there were several routines which parsed
implementation-specific formats, with a lot of duplicated code.
This class can be used directly, but it was primary designed so that its
two core functions (MQEncodePCF and MQDecodePCF) would be used as building
blocks for the implementation-specific formats, such as Performance Events
(MQSeries::Message::Event), Command server requests and responses
(MQSeries::Command::*), and the Publish/Subscribe administrative messages
(MQSeries::PubSub::AdminMessage).
This is a new class which provides an interface to the MQRFH Rules and
Format messages used by the Publish/Subscribe system. This can also be used
to create messages for working with the NEON MQIntegrator 1.X product
suites, since the format is the same, although the author hasn't actually
tried this yet.
This is a new subclass of MQSeries::Message which encodes/decodes complex
perl data structures using the XML-Dumper module. This was mostly done as a
proof of principle, and to please some XML zealots.
Note that the parsing of XML is much more expensive than the Storable
approach, and if you have a perl process on the sending and receiving end
of a message flow, the author still recommends using Storable.
This requires the CPAN XML::Dumper and XML::Parser modules.
- More complete documentation
-
The various strings used to represent the PCF parameters and values have
finally been documented, so someone other than the author may actually be
able to use this code.
- Extended to V5.1 PCF Commands
-
All of the new Commands for V5.1 are supported, and in fact, even if you
compile the MQSeries API with 5.0, you can still use the new commands, and
parse the resulting PCF parameters. The code which maps numeric parameters
to key strings has been ``flattened'' such that it doesn't use the actual C
macros.
These files (MQSeries/Command/PCF/*.pl) were auto-generated on an MQSeries
5.1 host, so the macro-to-number mapping has already been done, and it is
not necessary for the C macro to have been compiled into constants.c.
- Extended to V2.1 MQSC Commands
-
Most, but not all, of the MQSC commands (i.e. commands sent to an MQSC-only
command server, for example an MVS queue manager) have been supported, and
the API can parse all of new V2.1 object attributes (like ``ALTDATE'' and
``ALTTIME'').
WARNING: The MQSC code has not been extensively tested, so use it with
caution.
- NoAutoConnect option
-
The call to MQCONN is normally done in the constructor, but if it fails,
the error checking semantics are ugly. A new option (NoAutoConnect)
disables the implicit call to ->Connect(), and allows the developer to
make this call, and error check it explicitly.
The Connect()
method is also new.
- Inquire/MQINQ Support
-
Method calls have added to support the
MQINQ()
call against
the queue manager itself. This includes both Open()
and
Close()
methods, which were not previously available.
The Open()
method is also new, although it is just a rename of
the older semi-private _mqopen()
method call.
- NoAutoOpen option
-
The call to MQOPEN is normally done in the constructor, but if it fails,
the error checking semantics are ugly. A new option (NoAutoOpen) disables
the implicit call to ->Open(), and allows the developer to make this
call, and error check it explicitly.
- Inquire/Set MQINQ/MQSET Support
-
Method calls have added to support the
MQINQ()
and
MQSET()
calls against queues.
- Close method call
-
Objects can now be explicitly closed. In previous releases this was done
via the object destructor, and thus couldn't be error checked. Implicit
closing is still preferred, but CloseOptions can be given to the
constructor to control how the object is closed.
This is particularly useful for creating permanent dynamic queues (which
can accept persistent messages) which are purged and deleted upon close.
- Null-valued macros properly supported
-
There are several macros, such as MQCI_NONE, which are a fixed length
string of null characters. These were not properly defined in the
constants.c file, and thus couldn't be used as expected.
Now, these macros all evaluate to a string of nulls of the correct length,
this you can use them precisely as documented in the MQI docs.
- MQParseEvent, MQCommandRequestPCF, MQCommandResponsePCF and MQParseDeadLetter
-
These core module subroutines were removed.
MQParseDeadLetter never worked, and it will be implemented (eventually) in
the same way that MQSeries::Message::RulesFormat was done, with its own XS
source file.
The other 3 all dealt with very specific implementations of the PCF format,
and these were replaced by the MQSeries::Message::PCF class, which provides
very generic PCF parsing and encoding routines (MQEncodePCF and
MQDecodePCF).
Mapping the generic PCF into message format specific data is done by
``private'' class methods _TranslatePCF in each of the relevant OO modules.
This was a key prerequisite for developing MQSeries::PubSub::AdminMessage,
which is also based on a PCF message format. Future implementations of
special formats based on PCF should be easy. Of course, now IBM wants to
move to XML for everything, so...
- MQReasonToStrings
-
This subroutine's implementation was dramatically reworked.
This used to be implemented in C, inside the XS routine, but now the hash
of key/value pairs mapping a numeric ReasonCode to a readable test string
is done via a pair of automatically compiled files
(MQSeries/Constants/Reason*.pl)
In fact, all of the files in MQSeries/Constants are auto-generated from
templates in src/pre.in, by the tool src/util/flatten_macros. This is a
huge win, as it basically does the macro-to-value mapping such that the
perl API is dealing with raw numbers.
There is a non-trivial startup cost otherwise, as each and every macro has
to be looked up in the symbol table, the AUTOLOAD function called, a C
subroutine called, etc. This saves a few seconds of startup time.
- XS code streamlined
-
Most of the non-MQI subroutines were removed entirely, or moved elsewhere.
The MQSeries.xs.in directory is much more lean.
- XS code no longer leaks memory
-
The author now fully understands the XS concepts of mortality and reference
counts, and the code returns correctly mortalized, and properly reference
counted values.
- Support for "default" queue manager
-
The QueueManager key is no longer required by most of the OO API
constructors. If you have configured a default queue manager for your
environment, then you can use it with the OO API as of this release.
Before, the QueueManager key was required to have a true value, and since
the default queue manager is ``'', and ``'' is false...
- 004 required, not 5.005
The 5.005 prerequisite was relaxed to 5.004, and the requirement that the
perl interpreter itself be linked directly with -lthread (or -lpthread, or
whatever) was removed. The MQSeries.so libraries are themselves compiled
with the appropriate dependencies on libthread, and this code now works
fine with a standard, out-of-the-tarball compile of perl5.004 or later.
- New CONFIG parameters
-
It is now possible to explicitly disable either the server or client API
compile. The Makefile.PL now does a more generic job of determining whether
or not you appear to have support for the server API, which is the more
common case (eg. Linux, SunOS and IRIX only have client implementations
available).
At least one site didn't support clients at all, and they didn't want to
build in the support, so they can now turn it off via CONFIG.
- MANIFEST and .exclude auto-generated
-
These files are now auto-generated by development utilities in the util
subdirectory, rather than being updated manually.
This release required 5.005, built with thread support (this restriction
was subsequently removed in 1.06).
- MQServer::MQSeries made optional
-
Compilation of the MQServer::MQSeries API is automatically disabled on
SunOS 4.1.3 and IRIX hosts, for which we do not have a server API.
- constants.c.PL added
-
The huge, growing list of MQSeries C macros are now extracted from the
MQSeries C include files automatically, and the
@EXPORT
list
is built dynamically. The code for constants.c is also auto-generated, and
the code handles several different types of constant (hex, string,
character, etc).
The code also parses all of the available C header files, and makes all
possible macros available. This makes maintenance of the macro list easy,
but it does result in significant bloat of the namespace exported by
MQSeries. So be it.
- Test suite
-
The test suite was reorganized to a SysV-style rc.d directory syntax, with
files named 10foo.t, 20bar.t, etc.
- Distribution List Support
-
Support for Distribution lists was added to the core MQI functions, such as
MQOPEN, MQPUT and MQPUT1. This required a significant re-architecture of
these functions. The OO API classes were also extended to support dist
lists as well.
This functionality is all enabled only if one compiles with V5, of course.
- MQCONN retry logic
-
The MQCONN retry logic is disabled by default.
- MQOPEN retry logic
-
This was stripped out of the code entirely, since it never really worked,
and I doubt it ever would have. Bad idea.
- AutoResize logic
-
Logic was added to adjust the buffer size automatically, and retry an
MQGET()
call, when a truncated message is received, and
truncated messages are not accepted. This functionality is available in the
C++ API, the source of inspiration for the idea.
- Documentation
-
This module was finally documented, but only the object constructor and
basic methods were documented. Complete documentation of the command syntax
was not added until 1.06.
Supports explicit loading of MQClient::MQSeries or MQServer::MQSeries,
rather than implicit only.
Introduce the Command Server API, for both PCF and MQSC command messages.
Uses nfreeze, which is supposed to use network byte order, rather than
freeze.
- OO API
-
First implementation of the OO portion of the API
- XS source
-
Eliminated the dual XS file templates, using one source for both V2 and V5
- MQSeries core
-
Added two new utility functions to the core API:
MQParseEvent
MQReasonToText
- Locale hacks
-
MQSeries.pm will automagically set reasonable values for the LANG and
NLSPATH environment variables, if not set.
- Documentation
-
Significantly expanded documentation
- Introduced the extended test suite
-
- Dual client/server support
-
Introduced the dual namespaces to make client vs. server usage transparent.
That is, MQSeries.pm really pulls in MQServer/MQSeries.pm on a queue
manager, and MQClient/MQSeries.pm otherwise.
- PLMQ -> MQSeries
-
Change the module name from PLMQ to MQSeries, and changed the API calls
from GET to MQGET, etc., making the function mapping one to one.
- typemap.PL
-
Automated the typemap generation using a typemap.PL file