
=head1 Introduction

This file documents the changes to each and every release of the
MQSeries perl API, going back as far as the 1.02 release.

=head1 Changes for 1.10

=head2 MQSeries::Command MQSC bugs

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.

=head2 MQSeries::Message allows BufferLength of 0

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.

=head2 MQSeries::Command->CreateObject enhancements and documentation

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.

=head1 Changes for 1.09

=head2 Support for Win32

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.

=head2 Retry logic in MQSeries::QueueManager->Connect() and MQSeries::Queue->Open()

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.

=head2 MQSeries::Command->new takes additional arguments.

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.

=head2 MQSeries::Command->CreateObject() method added

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.

=head2 MQSeries::QueueManager Hconn reference counting

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.

=head2 MQSeries::QueueManager constructor arguments

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.

=head2 MQSeries::Queue->Open() ignores the Hobj on errors

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.

=head2 MQSeries::Message->Buffer() method added

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.

=head2 MQSeries::Message::Event->GetConvert() saves raw Buffer

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.

=head1 Changes for 1.08

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.

=head2 MQSeries::Message::Event was broken

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.

=head2 MQSeries::Command error checking enhancement

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.

=head2 MQSeries::QueueManager and MQSeries::Queue constructor bug

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.

=head2 MQSeries::Queue->Put() method wasn't setting MQPMO_FAIL_IF_QUIESCING

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.

=head2 MQSeries::PubSub::Broker/Stream API enhanced to support alternate users

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.

=head1 Changes for 1.07

This release is a minor bug fix release, but one of them is
significant enough to justify a public release.

=head2 MQSeries::Message::PCF memory leak

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.

=head2 Change to simplify static compiles

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.

=head2 Default Expiry values were wrong

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.

=head1 Changes for 1.06

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...

=head2 MQSeries::PubSub::*

The entire Publish/Subscribe API is new with this release.  This
includes the following modules:

=over 4

=item 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.

=item 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.

=item MQSeries::PubSub::Stream

This subclass of MQSeries::PubSub::Command, and MQSeries::Queue,
implements an interface to the Stream-specific Publish/Subscribe
commands.

=item MQSeries::PubSub::Message

This subclass of MQSeries::Message::RulesFormat provides an interface
for creating and parsing MQRFH-formated Publish/Subscribe messages.

=item 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.

=back

=head2 MQSeries::Message::PCF

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).

=head2 MQSeries::Message::RulesFormat

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.  

=head2 MQSeries::Message::XML-Dumper

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.

=head2 MQSeries::Command

=over 4

=item 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.

=item 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.

=item 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.

=back

=head2 MQSeries::QueueManager 

=over 4

=item 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.

=item 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.

=back

=head2 MQSeries::Queue

=over 4

=item 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.

=item Inquire/Set MQINQ/MQSET Support

Method calls have added to support the MQINQ() and MQSET() calls
against queues.  

=item 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.

=back

=head2 MQSeries core module

=over 4

=item 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.

=item 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...

=item 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.

=item XS code streamlined

Most of the non-MQI subroutines were removed entirely, or moved
elsewhere.  The MQSeries.xs.in directory is much more lean.

=item 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.  

=item 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...

=back

=head2 Installation Procedures, and other Miscellany

=over 4 

=item 5.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.

=item 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.

=item MANIFEST and .exclude auto-generated

These files are now auto-generated by development utilities in the
util subdirectory, rather than being updated manually.

=back

=head1 Changes for 1.05

This release required 5.005, built with thread support (this
restriction was subsequently removed in 1.06).

=head2 Installation Procedures

=over 4

=item 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.

=item 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.

=item Test suite

The test suite was reorganized to a SysV-style rc.d directory syntax,
with files named 10foo.t, 20bar.t, etc.

=back

=head2 MQSeries

=over 4

=item 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.

=back

=head2 MQSeries::QueueManager

=over 

=item MQCONN retry logic

The MQCONN retry logic is disabled by default.

=back

=head2 MQSeries::Queue

=over 4

=item 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.

=item 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.

=back

=head2 MQSeries::Command

=over 4

=item 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.

=back

=head1 Changes for 1.04

=head2 MQSeries

Supports explicit loading of MQClient::MQSeries or MQServer::MQSeries,
rather than implicit only.

=head2 MQSeries::Command

Introduce the Command Server API, for both PCF and MQSC command
messages.

=head2 MQSeries::Message::Storable

Uses nfreeze, which is supposed to use network byte order, rather than
freeze.

=head1 Changes for 1.03

=over 4 

=item OO API

First implementation of the OO portion of the API

=item XS source

Eliminated the dual XS file templates, using one source for both V2
and V5

=item MQSeries core

Added two new utility functions to the core API:

    MQParseEvent
    MQReasonToText

=item Locale hacks

MQSeries.pm will automagically set reasonable values for the LANG and
NLSPATH environment variables, if not set.

=item Documentation

Significantly expanded documentation

=back

=head1 Changes for 1.02

=over 4

=item Introduced the extended test suite

=item 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.

=item 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.

=item typemap.PL

Automated the typemap generation using a typemap.PL file

=back

=cut

#
# $Id: Changes.src,v 13.5 2000/04/12 14:24:31 wpm Exp $
#
# (c) 1999 Morgan Stanley Dean Witter and Co.
# See ..../src/LICENSE for terms of distribution.
#

