Previous Topic: 4.3.1 Definition and Methodology

Next Topic: 4.3.1.2 Indirect Exit Points

4.3.1.1 Direct Exit Points


Direct exit points apply to both the SAS Macro Statement and
the SAS Macro Language exit structures.  The following text
addresses each in turn.
SAS MACRO STATEMENT EXIT STRUCTURE

Every exit explained in this section is implemented by
inserting SAS code into an existing SAS macro stub.  The stub
routine is of the form:

    MACRO macro-name
    %

where macro-name   indicates the function and location of the
                   macro within the CA MICS code.

CA MICS exit SAS macro names all begin with an underscore and
are structured as follows:

    _USRxxxx     or
    _USRtfff

where xxxx  is a generic function name,
         t  is a 1-byte function code, and
       fff  is a file identifier.

These macros are stored in members called #cccEXIT on the
sharedprefix.MICS.SOURCE library, where ccc is the component
identifier.  The exit routines contained in these members
will apply to all database units in the CA MICS complex.

An example of such an exit member is #SMFEXIT, which contains
the file manipulation, accounting modification, and
operational exits for the Batch and Operations Analyzer.
This member includes the definition of the _USRSJOB macro,
which enables users to add or change elements on the BATJOB
file.  sharedprefix.MICS.SOURCE(#SMFEXIT) contains the
skeleton for the _USRSJOB macro (among others), which looks
like the following:

    .
    .
    MACRO _USRSJOB
    %
    .
    .

The exit members on the sharedprefix.MICS.SOURCE library are
not invoked directly.  Rather, the database unit logic
references the name of the member on the
prefix.MICS.USER.SOURCE library, which in turn %INCLUDEs the
exit member from the sharedprefix.MICS.SOURCE library.  For
our example, the database unit's user source library
contains an exit member called #SMFEXIT.  The contents of
prefix.MICS.USER.SOURCE(#SMFEXIT) are:

    /* some comments */
    %INCLUDE SOURCE(#SMFEXIT);
SAS MACRO LANGUAGE EXIT STRUCTURE

The general form of a direct Macro is:

    %MACRO exit-point-name;
     ...(content)...
    %MEND  exit-point-name;

where exit-point-name  indicates the function and location of
                       the Macro within the CA MICS code.

CA MICS direct exit point names are structured as follows:

    xxxxxxx

where xxxxxxx  is a generic function name.

Some CA MICS exit points are currently implemented through
the use of direct SAS Macro Language exit points.  An example
of a direct exit is the JCLEXIT exit point in the CA MICS JCL
generator.  See Section 4.3.2.3 in this guide for a detailed
description of this exit.

Regardless of the type of macro processing (Macro Statement
or Macro Language), some exits are intended for complex-wide
application.  Such exit logic is added to the exit member on
the source library for the complex, sharedprefix.MICS.SOURCE.
Thus, to add logic in our example, which will be executed at
the designated point in the daily SMF update process for all
database units on which the Batch and Operations Analyzer is
installed, put the code in source library member #SMFEXIT
between the macro name and the percent sign that follows, as:

contents of sharedprefix.MICS.SOURCE(#SMFEXIT):

    .
    .
    .
    MACRO _USRSJOB
     RETAIN MYCONST 5;
     JOBCPUTM = JOBCPUTM * MYCONST;
    %
    .
    .
    .

Some exits are intended for use by a specific database unit.
This is the case for exits to be used with CA MICS Accounting
and Chargeback.  For this purpose, exit routine invocation is
channeled through the prefix.MICS.USER.SOURCE library in each
database unit.  The previous definition of an exit macro can
be overridden by a definition added after the
sharedprefix.MICS.SOURCE library member is included.  In the
example, a _USRSJOB macro has been defined in
sharedprefix.MICS.SOURCE(#SMFEXIT).  To override this
definition for a particular database unit, redefine the macro
in prefix.MICS.USER.SOURCE(#SMFEXIT), as:

contents of prefix.MICS.USER.SOURCE(#SMFEXIT):

    /* some comments */
    %INCLUDE SOURCE(#SMFEXIT);
--->MACRO _USRSJOB
---> RETAIN MYCONST 4;
---> JOBCPUTM = JOBCPUTM * MYCONST;
--->%

The exit member referenced by the database unit's daily
update cycle is in prefix.MICS.USER.SOURCE.  In our example,
the daily SMF format routine (DYSMFFMT) would include
prefix.MICS.USER.SOURCE(#SMFEXIT), which itself includes
sharedprefix.MICS.SOURCE(#SMFEXIT).  The diagram below
illustrates the flow for any given database unit.

DYSMFFMT:

   |.
   |.
   |%INCLUDE USOURCE(#SMFEXIT);
   |
             prefix.MICS.USER.SOURCE(#SMFEXIT)
             contains:
             |.
             |.
             |%INCLUDE SOURCE(#SMFEXIT);
             |
                       sharedprefix.MICS.SOURCE(#SMFEXIT)
                       contains:
                       |
                       |.
                       |.
                       |MACRO _USRSJOB
                       |user code;
                       |%
                       |.
                       |.
             |.
             |.
   |.
   |.

To code an exit local to the database unit, you need to
redefine the macro in the prefix.MICS.USER.SOURCE library
member, after the sharedprefix.MICS.SOURCE library copy or
stub has been included.  In our example, _USRSJOB would be
redefined as:

DYSMFFMT:

   |.
   |.
   |%INCLUDE USOURCE(#SMFEXIT);
   |
             prefix.MICS.USER.SOURCE(#SMFEXIT)
             contains:
             |.
             |.
             |%INCLUDE SOURCE(#SMFEXIT);
             |
                       sharedprefix.MICS.SOURCE(#SMFEXIT)
                       contains:
                       |.
                       |.
                       |MACRO _USRSJOB
                       |shared user code;
                       |%
                       |.
                       |.
             |.
         --->|MACRO _USRSJOB
         --->|shared user code;
         --->|unit user code;
         --->|%
             |.
             |.
   |.
   |.

The definition of _USRSJOB in the user source library member
comes after the definition of the macro in the source library
as seen by the SAS compilation of the whole SMF update step.
The second macro definition completely overrides the first,
and thus the second definition must contain any code from the
first definition that is to be preserved.

This method has an inherent problem.  The shared exit code is
supposed to apply to all database units in the complex.  If
a change to the shared exit code is needed, the code must be
updated in the exit member both in sharedprefix.MICS.SOURCE
and in prefix.MICS.USER.SOURCE.  This creates a problem
because of the probability that the user source library
version of the logic update might be forgotten.

This situation can be avoided by a simple construction.
Define an extension macro for the macros that need to be
extended in this way.  The extension macro name would be of
the form _USRUfff, where fff is the file name.  The macro
reference must be in the original macro definition
(_USRSfff), and the stub for the _USRUfff macro must be
defined in sharedprefix.MICS.SOURCE(#cccEXIT).  Add the unit
database local code to prefix.MICS.USER.SOURCE(#cccEXIT),
under the macro name _USRUfff, and the entire code will
resolve correctly at the reference to _USRSfff.  In the SMF
example, modify the members as indicated by "--->" in the
following diagram:

   |.
   |.
   |%INCLUDE USOURCE(#SMFEXIT);
   |
             prefix.MICS.USER.SOURCE(#SMFEXIT)
             contains:
             |.
             |.
             |%INCLUDE SOURCE(#SMFEXIT);
             |
                       sharedprefix.MICS.SOURCE(#SMFEXIT)
                       contains:
                       |.
                       |.
                       |MACRO _USRSJOB
                       |shared user code;
                   --->| _USRUJOB
                       |%
                       |.
                       |.
                   --->|MACRO _USRUJOB
                   --->|%
                       |.
                       |.
             |.
         --->|MACRO _USRUJOB
         --->|unit user code;
         --->|%
             |.
             |.
   |.
   |.

This construction, using the _USRUfff macros, is applicable
to the various CA MICS components. Not all the _USRUfff macro
stubs that are possible are precoded for you by CA MICS, and
you must add the _USRUfff macro reference and stub to the
#cccEXIT member yourself if you wish to take advantage of
this method.  However, there are some exit macros that are
precoded with _USRUfff stubs.  Some of these precoded macros
are listed below:

File/        User         Exit
Accounting   Extension    Code
Macro        Macro        Location
----------   ----------   -----------------------------------
 _USRSJOB     _USRUJOB    sharedprefix.MICS.SOURCE(#SMFEXIT)
 _USRSPGM     _USRUPGM    sharedprefix.MICS.SOURCE(#SMFEXIT)
 _USRSSPL     _USRUSPL    sharedprefix.MICS.SOURCE(#SMFEXIT)
 _USRSCAC     _USRUCAC    sharedprefix.MICS.SOURCE(#CICEXIT)
 _USRSCSU     _USRUCSU    sharedprefix.MICS.SOURCE(#CICEXIT)
 _USRSIAC     _USRUIAC    sharedprefix.MICS.SOURCE(#IMSEXIT)
 _USRSISU     _USRUISU    sharedprefix.MICS.SOURCE(#IMSEXIT)
 _USRS_IS     _USRU_IS    sharedprefix.MICS.SOURCE(#IMSEXIT)
 _USRSSUA     _USRUSUA    sharedprefix.MICS.SOURCE(#IDMEXIT)
 _USRSSAC     _USRUSAC    sharedprefix.MICS.SOURCE(#IDMEXIT)
 _USRSTSI     _USRUTSI    sharedprefix.MICS.SOURCE(#TSOEXIT)
 _USRSTSC     _USRUTSC    sharedprefix.MICS.SOURCE(#TSOEXIT)
 _USRSTSU     _USRUTSU    sharedprefix.MICS.SOURCE(#TSOEXIT)
 _USRUJPJ     _PWRJPJB    sharedprefix.MICS.SOURCE(#PWREXIT)
 _USRUJPO     _PWRJPOA    sharedprefix.MICS.SOURCE(#PWREXIT)
 _USRUJPP     _PWRJPPG    sharedprefix.MICS.SOURCE(#PWREXIT)

This method of tailoring affords you great flexibility in
tailoring CA MICS and, because of the power of the SAS
language, is easy to do.  You should, however, always follow
these guidelines:

 -  Validate the fields your exits use to make their
    processing decisions.  While CA MICS does some basic
    validation, it cannot catch the kinds of installation
    specific errors you can (e.g., an invalid account number
    on a job card).  When one of your exits detects invalid
    input data, it should NEVER pass it on into the database
    (i.e., pass through an invalid account number so it
    becomes part of the key of a record).  Doing so will
    increase the size of the database and decrease its
    usefulness for analysis and reporting.  Rather, your
    exits should take some sort of standard default action
    when they detect invalid input data (e.g., assign a job
    with an invalid account code to an overhead category).

 -  Exit code is inserted directly into CA MICS processing
    logic.  It thus becomes the responsibility of the user to
    make certain that the code inserted will not do anything
    that would cause subsequent CA MICS logic to operate
    abnormally.