Exits
In IBM Content Manager OnDemand (Content Manager OnDemand), it is possible to use exit points to customize and enhance the standard functionality within the product. This chapter introduces various exit points within the Content Manager OnDemand product. By using working sample code, we present some examples of the types of operations and enhanced functions that are possible.
In this chapter, we cover the following topics:
11.1 Introduction to user exits
A user exit is a point during processing that enables you to run a user-written program and return the control of processing after your user-written program ends. There are a few different kinds of exits. In this chapter, we describe the exits based on the following categories:
ACIF Indexing
 – Input record exit
 – Index record exit
 – Output record exit
 – Resource exit
OS/390 indexer exits
 – Anystore exit
 – Input exit
 – Index exit
System administration
 – System log exit
 – Print exit
Customized functions
 – Load exit
 – Preview exit
 – Report specifications archive definition exit
 – Tablespace create exit
 – ARSYSPIN and sample APKACIF exit on z/OS
Content Manager OnDemand provides data at each exit that can serve as input to the user-written programs. Using these exits, it is possible to perform functions such as sending emails based on events in the system, updating index values through a print request, and cleaning up data as it is loaded into Content Manager OnDemand. There are infinite examples of what is possible from the Content Manager OnDemand exits. We provide some samples here that act as a guide for creating customized user exits programs.
 
Note: Always make a point to recompile all the customized user exits after upgrading the Content Manager OnDemand software because the header files might have changed with different versions.
PDF Indexer: The PDF Indexer does not support any user exits.
11.2 ACIF exits
The ACIF user exit is a point during the ACIF processing where control is handed from ACIF to a user-written program. After the user-written program is finished, the control is handed back to ACIF. There are four points during ACIF processing at which user programs can be configured: input, indexing, output, and resource.
 
Note: ACIF exits are called for every input, indexing, output, and resource record. They are not limited to being called only once per file.
In Multiplatforms, ACIF user exits must be written in C. In z/OS, ACIF user exits may be written in C, COBOL, or ASSEMBLER. For more information, see the section Special considerations for APKACIF exits written in COBOL” in IBM Content Manager OnDemand for z/OS, V9.0, Administration Guide SC19-3364. ACIF exits do not exist in Content Manager OnDemand for i.
For detailed documentation about each of these exit points, see IBM Content Manager OnDemand for Multiplatforms - Indexing Reference, SC19-3354 and IBM Content Manager OnDemand for z/OS and OS/390 - Indexing Reference, SC27-1375.
11.2.1 A new macro for user exits
Because the default installation directory changed for Content Manager OnDemand V9, the arsload program supports a new macro to make user exits more portable.
For example, instead of specifying the exit as INPEXIT=/opt/IBM/ondemand/V9.0/exits/acif/asciinpe, specify the following items in the indexing parameters:
INPEXIT=$(OD_ACIF_EXIT_DIR)asciinpe
arsload substitutes the correct path for the platforms.
This macro works for all four ACIF user exits. The macro is not supported if ACIF is run outside of arsload.
11.2.2 Input record exit
ACIF provides the input record exit that enables you to add, delete, or modify records in the input file before they are processed by ACIF. The primary purpose of this exit is to modify input records before ACIF sees them. The exit program is started by the ACIF inpexit parameter.
The input exit can be used to insert indexing information. More common uses are to remove null characters, truncate records, add carriage control, and change code pages. In general, indexer parameters should reflect what the input record looks like after the input exit runs. The only exception is the FILEFORMAT indexer parameter, which should correspond to the input record before it is passed to the input exit. For example, if the file contains ASCII data and uses the ASCII stream delimiter x’0A’, specify (NEWLINE=x’0A’), not (NEWLINE=x’25’), even if you are using the apka2e exit to convert ASCII to EBCDIC. Otherwise, ACIF does not pass the correct record to the apka2e input exit.
Content Manager OnDemand provides three input record exits:
apka2e
asciinp
asciinpe
You can either use these as samples to build from, or you can compile them and run them as is. These programs are documented in IBM Content Manager OnDemand for Multiplatforms - Indexing Reference, SC18-9235, and are described briefly in the following sections.
The apka2e exit
The apka2e exit translates data that is encoded in ASCII (code set IBM-850) into EBCDIC (code set IBM-037). If you are converting line data to AFP, consider converting the data to EBCDIC. There is a much wider selection of EBCDIC coded fonts than there are ASCII, and many customers find it easier to use ones that are supplied by IBM than to create their own character sets and code pages. To use these predefined EBCDIC coded fonts, the data must be in EBCDIC.
When you use the apka2e exit, you must manually change your
indexing parameters:
Change an ASCII CPGID to an EBCIDIC one, for example, change CPGID=850 to CPGID=500.
Change the HEX codes for the triggers and index names from ASCII to EBCDIC. If you do not do this, you receive ACIF return code 16, stating that it cannot find trigger1 or any fields.
We used a hex editor to determine the new EBCDIC values and typed them by keyboard edit into the parameter file. If you do not have a hex editor, you can find conversion tables on the Internet.
For more information about how to update indexing parameters, see 11.2.6, “Debugging input user exit programs” on page 293.
The asciinp exit
The asciinp exit program is used when the data does not contain carriage controls but contains “PC style” carriage returns and form feeds X’0D0A’ and X’0D0C’. This IBM provided program transforms the ASCII data stream into a format that contains a carriage control character in byte 0 of every record.
The asciinp exit performs the following actions:
Inserts a new page command (X’31’) at the top of the first page.
Removes the ASCII carriage return (X’0D’).
Inserts an ASCII new line (X’20’) carriage control at byte 0 of each line, except the first line on a new page.
Replaces the ASCII form feed (X’0C’) with an ASCII new page command (X’31’).
Leaves X’0A’ in the file.
 
Note: Because asciinp inserts carriage control characters in byte 0 of your document, and leaves X’0A’, it changes the position of the triggers and fields. If you use this exit, you must add 1 to the column offsets for the triggers
and fields.
The asciinpe exit
The asciinpe exit performs a combination of the previous two exits. It converts the data from ASCII to EBCDIC and inserts EBCDIC carriage control characters. For full documentation about this sample program, see the asciinpe.c
source code.
11.2.3 Index record exit
The index record exit allows you to modify or ignore the records that ACIF writes in the index object file. The program, which specified in the ACIF indxexit parameter, receives control just before a record is written to the index object file. The user-written program can tell ACIF to use the record, not to use the record, or to perform some sort of editing on the record before inserting it into the index
object file.
A good use of this program is for an application that must pull an index from a source other than the document. The application group can be set up with a default index; then, the user exit program can grab the appropriate index from this secondary source and replace the default value that was in the index record. The record is then sent back to ACIF.
Another example is to modify the format of an existing index. Example 11-1 shows a sample index exit C program to update the date format from mmddyy to mm/dd/yy.
 
Important: The ACIF index file is in AFP format. It is important to understand the structure of AFP before writing or modifying an index exit.
Example 11-1 Sample ACIF index exit program
#define _c_APKIND
/*********************************************************************/
/* */
/* MODULE NAME: UPDDATE.C */
/* */
/* SYNOPSIS: ACIF Sample Index Exit */
/* */
/* */
/* DESCRIPTION: This module converts the date format */
/* from mmddyy to mm/dd/yy before adding the */
/* record to the index object file */
/* */
/*********************************************************************/
#include "apkexits.h "/* standard acif exit header file */
 
long
INDXEXIT( INDXEXIT_PARMS *exitstruc )
{
int i;
 
if ( exitstruc->eof != IDX_EOFLAG )
{
/************************************************/
/* Look for TLE with attribute name "mmddyy" */
/************************************************/
if (
(exitstruc->record[13] == 0x6D) &&
(exitstruc->record[14] == 0x6D) &&
(exitstruc->record[15] == 0x64) &&
(exitstruc->record[16] == 0x64) &&
(exitstruc->record[17] == 0x79) &&
(exitstruc->record[18] == 0x79))
{
 
/************************************************/
/* TLE length is now 40 (was 38) */
/************************************************/
 
exitstruc->record[ 2] = 0x28;
 
/************************************************/
/* Attribute value count is now 12 (was 10) */
/************************************************/
 
exitstruc->record[19] = 0x0C;
 
/************************************************/
/* Relocate attribute qualifier triplet X'80' */
/************************************************/
 
for (i=40; i>30; i--)
exitstruc->record[i] = exitstruc->record[i-2];
 
/************************************************/
/* Change mmddyy to mm/dd/yy */
/************************************************/
 
exitstruc->record[30] = exitstruc->record[28];
exitstruc->record[29] = exitstruc->record[27];
exitstruc->record[28] = 0x61;
exitstruc->record[27] = exitstruc->record[26];
exitstruc->record[26] = exitstruc->record[25];
exitstruc->record[25] = 0x61;
 
 
/**********************************************/
/* record length has increased to 41 (was 39) */
/**********************************************/
 
exitstruc->recordln = 41;
 
}
 
exitstruc->request = IDX_USE;
}
 
return( 0 );
}
11.2.4 Output record exit
The output record exit allows you to modify or ignore the records that ACIF writes to the output document file. The program is started by the ACIF outexit parameter, and it gives control to the user program before a record (which may be a structured field or may be line data) is written to the output (.out) file.
Example 11-2 shows a sample output exit program that deletes records from the output file. This program checks each structured field to determine whether it is an AFP record. If the record does not begin with Hex 5A, the exit program tells ACIF not to use this record.
 
Important: The ACIF output file may be in either line data or AFP format. If the ACIF output file is in AFP format, it is important to understand the structure of AFP before writing or modifying an output exit.
Example 11-2 Sample ACIF output exit program
#define _c_ACCT_OUT
/*********************************************************************/
/* */
/* MODULE NAME: ACCT_OUT.C */
/* */
/* */
/* SYNOPSIS: ACIF Output Exit */
/* */
/* DESCRIPTION: This program will delete all non-AFP records (or */
/* records that do not begin with X(5A) from the */
/* output object before giving control back to ACIF */
/* */
/*********************************************************************/
/* Standard acif exit header file */
/************************************************/
*/
#include "apkexits.h"
 
long
OUTEXIT( OUTEXIT_PARMS *exitstruc )
{
 
/************************************************************************/
/* Delete all records from the output that do not begin with Hex '5A' */
/************************************************************************/
 
if(exitstruc->eof != ACIF_EOF)
{
if(exitstruc->record[0] == 0x5A)
exitstruc->request = ACIF_USE;
else
exitstruc->request = ACIF_DELETE;
}
return( 0 );
}
11.2.5 Resource exit
If you want to prevent ACIF from collecting a specific type of resource, such as overlays, you can control this with the ACIF restype parameter. However, if you want to prevent ACIF from writing a specific resource to the resource file, use the resource exit.
The resource exit is best used to control resources at the file name level. For example, suppose that you want to exclude particular fonts from the resource file. You can code this exit program to contain a table of the fonts that you want to exclude and filter them from the resource file. The program that is invoked at this exit is defined in the ACIF resexit parameter.
ACIF does not start the exit for the following resource types:
Page definitions: The pagedef is a required resource for converting line data to AFP and is never included in the resource file.
Form definitions: The formdef is a required resource for processing print files. If you do not want the formdef to be included in the resource file, specify restype=none or explicitly exclude it from the restype list.
Coded fonts: If you specify MCF2REF=CF, ACIF writes coded fonts to the resource file if they are included in the restype list. By default (MCF2REF=CPCS), ACIF does not write coded fonts to the resource file.
11.2.6 Debugging input user exit programs
When working with an input exit, it is necessary to know how the exit changed your data before you load it. A way to determine how the exit changed the data is to set up ACIF to run in stand-alone mode (not called from arsload).
To set up ACIF to run in stand-alone mode, create an indexing parameter file with no triggers, fields, or indexes that are defined, and use the value CONVERT=NO. Include your input file, output file, and the input exit routine in the parameter file. Then, run arsacif from a command line while pointing to this parameter file. Example 11-3 shows our ACIF parameter file, parmfile. Use the following command to run stand-alone ACIF:
arsacif parmdd=parmfile
This command starts ACIF with the user exit, runs the exit, and writes the output to the file specified by the OUTPUTDD parameter. You can inspect the output file to make sure that the exit did what you expected. You can also use this output file in the graphical indexer to index your post-exit file because the exit routine might change the location of your triggers and fields.
Example 11-3 ACIF parameter file
CC=YES
CCTYPE=Z
CONVERT=NO
CPGID=850
FILEFORMAT=STREAM,(NEWLINE=X’0A’)
INPUTDD=C: empilling_input.txt
OUTPUTDD=C: empilling_input.txt.out
RESTYPE=NONE
INPEXIT=C:Program FilesIBMOnDemand for WindowsV9.0exitsacifasciinp.dll
 
 
 
 
 
 
Important: Specify the complete path in the inpexit, indxexit, resexit, or outexit parameters. There is nothing more frustrating than trying to debug an exit that is never called because another exit with the same name is being invoked because of the PATH environment variable.
Another method is to run arsload with the -i option, which runs only the indexer and does not load any files. In this case, it is not necessary to add INPUTDD or OUTPUTDD to the indexing parameters in the application. Running arsload with the -i option creates the .ind and .out files, and leaves them on the system for you to view.
11.3 OS/390 indexer exits
The OS/390 indexer can be used to extract index data from and generate index data about line data and AFP reports. In addition, other data types, such as TIFF images, can be captured by using the anystore exit. The OS/390 indexer is available on the z/OS platform for all versions and on the AIX platform beginning with Content Manager OnDemand V9.0. There are three OS/390 indexer exits: ANYEXIT, INPEXIT, and INDXEXIT.
11.3.1 The ANYEXIT exit
ANYEXIT is the anystore exit, which captures any type of data. The exit reads the data to be captured, breaks it into documents, and determines the index values. The sample anystore exit captures TIFF images by using a pre-generated set of indexing instructions that are read from a separate file.
The anystore batch capture exit can be used to provide all segment and index data to the report capture program. This exit program is called from the report capture process.
The exit is called dynamically during the capture process. The capture program calls the exit when the indexing instructions for the application include the ANYEXIT parameter. The report administrator provides a program name for the anystore exit.
The report capture program expects the anystore exit to pass back all segment data and the associated index information. The capture program performs only the data management functions that are required for the capture process (document compression, document store, index management and store, and
so on).
A sample COBOL exit is provided in ARSEXANY, which is found in member SARSINST(ARSEXANY) along with the COBOL copy book ARSANYBK. A sample C exit is provided in ARSECANY, which is found in member SARSINST(ARSECANY) along with the C header files ARSANYBH
and ARSZ390H.
11.3.2 The INPEXIT exit
INPEXIT is the input exit, which is provided to allow more processing of the report input before the report is stored. This exit can be used only when the INDEXSTYLE is not set to AFP and when the ANYEXIT is not specified. The exit is called dynamically during the report capture process. The report capture routine calls the exit when the indexing parameters specify an input exit name in the
INPEXIT parameter.
The report administrator provides a program name for this parameter.
There are no restrictions as to the type of processing that can be performed in an input exit with the exception that the exit must pass the standard parameter list back to the report capture program. Values must be supplied for all parameters.
Beginning with Content Manager OnDemand for z/OS V8.4 or later, a line print file can have a fixed record length greater than 512 or a variable record length. To support this capability, a new parameter format is provided. The old parameter format is still supported for compatibility with earlier versions.
To lean more about creating an input exit, details concerning the new parameter format, and how Content Manager OnDemand determines whether to use the old or new parameter format, see IBM Content Manager OnDemand for z/OS and OS/390 - Indexing Reference, SC27-1375.
11.3.3 The INDXEXIT exit
INDXEXIT is the index exit, which is provided to allow the report indexes to be modified before insertion into the Application Group data table. This exit can be used with any type of report that is captured by the OS/390 indexer. The exit is called dynamically during the capture process. The capture program calls the exit when the indexing instructions for the application include the
INDXEXIT parameter.
The report administrator provides a program name for the index exit.
There are no restrictions as to the type of processing that can be performed in an index exit with the exception that the exit must pass the standard parameter list back to the capture program. A sample COBOL exit is provided in ARSEXNDX, along with the COBOL copy book ARSINDBK. A sample C exit is provided in ARSECNDX along with the C header file ARSINDBH.
For more information about the OS/390 indexer, see IBM Content Manager OnDemand for z/OS and OS/390 - Indexing Reference, SC27-1375.
11.4 System administration
In this section, we describe exits that are used for system administration: system message logging and server printer configuration. These exits are in the bin directory of the Content Manager OnDemand installation.
11.4.1 System log exit for Multiplatforms
The Content Manager OnDemand system log is a tool that is used by administrators. You can use the Content Manager OnDemand Administrator Client to configure Content Manager OnDemand to record information, warning, and error messages in the system log. Content Manager OnDemand records messages, such as when users log on and log off the system. Content Manager OnDemand also records messages for application group activity, such as when clients query and retrieve data. Each operation that is performed by a user that involves a connection to the Content Manager OnDemand server can be logged. The detail that is captured within the system log can be configured so that only certain messages are retained, and others can be discarded.
In addition, you can configure Content Manager OnDemand to send these messages to the arslog exit. The system log exit is supplied in the arslog file that is in the bin directory of the Content Manager OnDemand installation root for each respective platform. If the arslog file is opened in a text editor, it simply contains comments that provide a brief description of the exit and the order of the parameters that Content Manager OnDemand hands to this exit. By default, the system log exit is not initialized within Content Manager OnDemand. Therefore, if you edit the arslog file to capture information, the exit does not
run automatically.
To activate the system log exit, complete the following steps:
1. Start the Administrator Client and log on to the server on which you intend to use the system logging exit.
2. Right-click the name of the server in the list and select System Parameters, as shown in Figure 11-1.
Figure 11-1 Select Content Manager OnDemand system parameters
3. To choose a User Exit Logging option, select the option.
 
Tip: The arslog exit file is run by the same user that owns the arssockd process that is calling this exit. A common reason for getting no response from this exit is access permissions on either the arslog file itself or files and directories that are being accessed within arslog.
Content Manager OnDemand provides an exit for each of the four system logging event points. These exits allow you to filter the messages and take action when a particular event occurs. For example, you can provide a user exit program that sends a message to a security administrator when an unsuccessful logon attempt occurs.
System log exit samples
To demonstrate some of the most common uses for the system log exit, we provide two typical examples:
For simplicity, we have not demonstrated the system log exits across all supported platforms. We recognize that the scripting languages between platforms do vary, but the principles that we describe here are uniform across all supported platforms; only the syntax differs.
Capturing failed logon attempts (AIX)
Example 11-4 is an extract from a simple system logging exit that captures message code 31 (a failed logon attempt) and writes the user ID that was used and some information about the network address of this user to a file. In this case, the file name is a combination of the system date and the string failedlogon.log. This system log exit writes all of the failed logon attempts for each day to a file that can then be sorted and analyzed by other utilities to alert for possible security risks.
Example 11-4 Capturing failed logon attempts (AIX)
# $1 - OnDemand Instance Name
# $2 - Time Stamp
# $3 - Log Identifier
# $4 - Userid
# $5 - Account
# $6 - Severity
# $7 - Message Number
# $8 - Message Text
#
case $7 in
31) echo $4 $8 >> /home/archive/`date +"%d-%m-%Y"`failedlogon.log;;
*) echo $@ > /dev/null;;
esac
 
exit 0
For the exit sample that is provided in Example 11-4 on page 299, we also have provided a small sample of what the output of this exit might look like (Example 11-5). For example, you can see in the output that is provided that several unsuccessful attempts were made from the same machine and different user IDs were used for each attempt. In this example, by adding parameter 2 ($2) to the output and resorting the file, we can further establish the time of
these attempts.
Example 11-5 Sample exit output
ADMIN Failed login: GB55102K3.myServer.ibm.com 9.9.9.9
MARTIN Failed login: GB55102K3.myServer.ibm.com 9.9.9.9
FRED Failed login: GB55102K3.myServer.ibm.com 9.9.9.9
USER1 Failed login: GB55102K3.myServer.ibm.com 9.9.9.9
USER2 Failed login: GB55102K3.myServer.ibm.com 9.9.9.9
Notifying another system when a load completes (AIX)
This sample is used in a production environment where the number of load jobs that are sent to Content Manager OnDemand must be controlled so that the next load job is sent only when the previous one completed successfully. In this case, this is because there is a limited amount of disk space in the location on the Content Manager OnDemand server where the load files are received from the remote machine, and because the load files are large.
Example 11-6 shows how the exit collects virtually all of the available information when it receives message number 87 (a successful load). This information is then used as the input for another script, which notifies the remote machine that the load is complete and the next report file can be sent.
Example 11-6 Controlling load jobs (AIX)
# $1 - OnDemand Instance Name
# $2 - Time Stamp
# $3 - Log Identifier
# $4 - Userid
# $5 - Account
# $6 - Severity
# $7 - Message Number
# $8 - Message Text
#
 
# if [ $6 = "3" ]; then
# print $@ >> /home/archive/InfoMsg.log
# fi
 
case $7 in
#
# msg num 87 is a successful load
#
87) echo "Instance : $1" >> /arsacif/companyx/arslog.out
echo "Time Stamp : $2" >> /arsacif/companyx/arslog.out
echo "Log Identifier : $3" >> /arsacif/companyx/arslog.out
echo "Userid : $4" >> /arsacif/companyx/arslog.out
echo "Account : $5" >> /arsacif/companyx/arslog.out
echo "Severity: $6" >> /arsacif/companyx/arslog.out
echo "Message Number: $7" >> /arsacif/companyx/arslog.out
echo "Message Text : $8" >> /arsacif/companyx/arslog.out
/arsacif/companyx/control_file.scr "$@" >> /arsacif/companyx/arslog.out ;;
*) ;;
esac
 
exit 0
 
Tips: For more information about the codes for each of the message types that are logged in the system log, see Chapter 2, “Common Server Messages”, in IBM Content Manager OnDemand - Messages and Codes, SC27-1379. For example, message number 87 is listed as ARS0087I.
11.4.2 System log exit for z/OS
Content Manager OnDemand can be configured to record information, warning, and error messages. You can set up Content Manager OnDemand to record these messages by using the system log exit that is named the ARSLOG installation exit. The implementation of the system log exit on z/OS is different from those on Multiplatforms. Like other z/OS exits, it uses the MVS Dynamic Exit Facility.
The configuration of the system log exit is done with the Administrator Client in the Systems Parameters window (see Figure 11-2).
Figure 11-2 System Parameters window with User Exit Logging selected
Make the selections for the system logging and set up the exit. The sample in Example 11-7 routes the messages to the system log with the WTO Macro.
Example 11-7 System log exit setup sample
ARSLOG title 'Issue a message to syslog' 00010000
****************** START OF MODULE SPECIFICATIONS ******************* 00020000
* * 00030000
* * 00040000
* ==> OD/390 - 5655-H39 <== * 00050007
* * 00060000
* Module Name: ARSLOG * 00070000
* * 00080000
* Descriptive Name: Issue a message to syslog * 00090000
* * 00100000
* Status: Version ? Release ? * 00110000
* * 00120000
* Function: This routine issues a message to the SYSLOG * 00130000
* * 00140000
* Copyright: 5655-H39 (C) Copyright IBM Corp. 2013 * 00150007
* Licensed Materials-Property of IBM * 00160000
* See Copyright instructions. * 00170000
* * 00180000
* Notes: * 00190000
* * 00200000
* Restrictions: None * 00210000
* * 00220000
* Register * 00230000
* Convention: R1 points to the Parameter list * 00240000
* R12 base register 00250000
* * 00260000
* Patch Label: PSPACE * 00270000
* * 00280000
* Input: Parameter list pointed to by Register 1 * 00290000
* Parameter list contains addresses of: * 00300000
* - message length * 00310000
* - message text * 00320000
* * 00330000
* Output: None * 00340000
* * 00350000
* Return codes: * 00360000
* * 00370000
* NORMAL: R15 = return code from WTO * 00380000
* * 00390000
* Exits: Return to caller via BR 14 * 00400000
* * 00410000
* External References: * 00420000
* * 00430000
* Change Activity: See below * 00440000
* * 00450000
* Ver Rel Mod Date Description of Change * 00460000
* ___________ ________ _______________________________________ * 00470000
* 0? 0? 00 04/05/00 Release ?.? * 00480000
* * 00490000
******************** END OF MODULE SPECIFICATIONS ******************* 00500000
ARSLOG csect 00510000
ARSLOG rmode any 00520000
ARSLOG amode 31 00530000
using *,r15 00540000
b pastcopy 00550000
dc C'ARSLOG &sysdate' 00560000
dc C'5622-662 (C) COPYRIGHT IBM CORP. 2013' 00570000
dc C'ALL RIGHTS RESERVED' 00580000
dc C'LICENSED MATERIALS-PROPERTY OF IBM' 00590000
pastcopy ds 0h 00600000
stm 14,12,12(r13) 00610001
lr r12,r15 00620000
lr r2,r1 00630000
using plist,r2 00640000
drop r15 00650000
using ARSLOG,r12 00660000
storage OBTAIN,length=workl,loc=ANY,cond=YES 00670000
ltr r15,r15 00680000
jnz bagit 00690000
st r13,4(,r1) 00700000
st r1,8(,r13) 00710000
lr r13,r1 00720000
using workarea,r13 00730000
* 00740000
* Determine the message length 00750005
* 00760000
slr r1,r1 Number of bytes 00770005
l r15,msgtxta get starting address 00780005
nulloop ds 0h 00790006
cli 0(r15),x'00' Is it zero? 00800005
je nomore Yes - quit 00810005
la r1,1(,r1) Bump count 00820005
la r15,1(,r15) bump address 00830005
j nulloop And try next 00840005
nomore ds 0h 00850005
lr r3,r1 Save length of message 00860005
mvc msgtxt+2(3),=c'XXX' Set the prefix 00870007
la r14,msgtxt+5 Start to place number 00880005
l r15,msgnum Get start of message number 00890005
numloop ds 0h 00900005
cli 0(r15),x'00' Null? 00910005
je nomove 00920005
mvc 0(0,r14),0(15) move it 00930005
la r14,1(,r14) next destination 00940005
la r15,1(,r15) next source 00950005
j numloop go do next 00960005
nomove ds 0h 00970005
l r15,sev Get severity 00980005
cli 0(r15),c'1' Is it Alert 00990005
jne tryerror No skip 01000005
mvi 0(r14),c'E' Set error severity 01010006
j donesev 01020005
tryerror ds 0h 01030005
cli 0(r15),c'2' "Error" severity? 01040005
jne trywarn No - skip 01050005
mvi 0(r14),c'E' Set error 01060005
j donesev 01070006
trywarn ds 0h 01080005
cli 0(r15),c'3' Is it Warning 01090006
jne setinfo 01100005
mvi 0(r14),C'W' Set Warning 01110005
j donesev 01120005
setinfo ds 0h 01130005
mvi 0(r14),c'I' Indicate info 01140005
donesev ds 0h 01150005
mvi 1(r14),c' ' Put in blank 01160005
la r14,2(,r14) Skip 01170005
01180005
c r3,=f'60' More than 60 chars 01190005
jnh singlwto No - issue it 01200005
lhi r3,60 Only first 60 chars 01210005
01220005
* We only need to issue a single WTO 01230005
01240005
singlwto ds 0h 01250005
la r4,msgtxt+2 Get start of text 01260005
lr r15,r14 Get where we stopped 01270005
sr r15,r4 Get how much we've done 01280005
ar r15,r3 add length of text 01290005
stcm r15,b'0011',msgtxt Set the length 01300005
bctr r3,0 subtract 1 01310005
l r15,msgtxta Get source address 01320005
ex r3,mvcins Move it 01330005
01340000
mvc wtoe,wto1 init the execute form 01350007
la r3,msgtxt 01360005
slr r0,r0 01370000
wto text=(r3),mf=(E,wtoe) 01380005
j exit exit 01390000
01400000
02250000
exit ds 0h 02260000
lr r1,r13 02270000
l r2,4(r13) 02280002
storage RELEASE,length=workl,addr=(r1) 02290003
lr r13,r2 02300002
drop r13 02310000
02320000
bagit ds 0h 02330000
lm 14,12,12(r13) 02340001
br r14 02350000
psize equ ((*-ARSLOG+99)/100)*5 02360000
dc C'PATCH AREA - ARSLOG &sysdate' 02370000
pspace dc 25s(*) 02380000
org pspace 02390000
dc ((psize+1)/2)s(*) 02400000
02410000
02420000
mvcins mvc 0(0,r14),0(r15) 02430000
02450000
wto1 wto text=, +02460000
desc=(6), +02470000
mcsflag=(BUSYEXIT), +02480000
routcde=(11), +02490000
mf=L 02500000
wto1l equ *-wto1 02510000
ltorg 02520005
02530005
workarea dsect 02870000
rsa ds 18f 02880000
wtoe ds cl(wto1l) 02890006
msgtxt ds cl(72) 02900005
workl equ *-workarea 02910000
02920000
plist dsect 02930000
instance ds a 02940005
tstamp ds a 02950005
logrec ds a 02960005
userid ds a 02970005
acct ds a 02980005
sev ds a 02990005
msgnum ds a 03000005
msgtxta ds a 03010005
03020005
yregs , 03030007
iezwpl 03040005
end , 03050005
When the exit routine is assembled and link-edited to a library, it must be associated with the exit in one of two ways:
Use the exit statement in PROGXX parmlib member. For more information about the PROGXX parmlib member, see z/OS MVS Initialization and Tuning Reference, SA22-7592.
Use the SETPROG EXIT operator command. For more information about the SETPORG EXIT command, see z/OS MVS System Commands, SA22-7627.
To activate the exit routine, run the following command:
SETPROG EXIT,ADD,EXITNAME=ARSLOG,MODENAME=ARSLOG, DSN=TEAM5.LOADLIB
The exit was link-edited to a normal library that is not AFP authorized.
11.4.3 Print exit for Multiplatforms
A Content Manager OnDemand printer is an interface between the user and a print device that is controlled by a server. There are multiple ways to print a document that is stored in Content Manager OnDemand:
Local printing: This is accomplished through a LAN attached PC printer.
Server printing: This is accomplished by submitting a print job to print server queue, for example an IBM Infoprint Server print queue. Infoprint is an intelligent printer driver that provides AFP capabilities for Content Manager OnDemand servers.
A server print device can be physically connected to the library server or attached to another workstation in the network. Server print devices are managed by Infoprint.
Content Manager OnDemand provides a print exit for Multiplatforms that can be used only for documents that are printed through a server printer.
There are two print exits that are available for Multiplatforms, which are in the bin directory of the Content Manager OnDemand installation root for each platform:
arsprt: Content Manager OnDemand User Exit Printing Facility
arsrdprt: Content Manager OnDemand User Exit Printing Facility for
Report Distribution
If either of the files are opened in a text editor, notice that they contain comments that provide a brief description of the exit and the order of the parameters that Content Manager OnDemand gives to this exit.
Example 11-8 shows an arsprt file, which updates application group indexes for a certain document type each time it is sent to a server printer. This is a real example from a customer where the requirement is for Content Manager OnDemand to keep a record of when a document is reprinted. This file is achieved by using the print exit to update the indexes of a document to show the last time that the document was reprinted and a counter is incremented to log the number of times the document has been reprinted. Comments are inserted into the sample script in Example 11-8 that explain what each part of the script is doing. The customer name and the IP addresses either have been altered or removed for reasons of confidentiality.
Example 11-8 Sample arsprt print exit file
#!/bin/ksh
#
# arsprt - OnDemand User Exit Printing Facility
#
# 5622-662 (C) COPYRIGHT IBM CORPORATION 2013
# All Rights Reserved
# Licensed Materials - Property of IBM
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
# This program sample is provided on an as-is basis.
# The license of the OnDemand product is free to copy, revise,
# modify, and make changes to this sample program
# as see fit.
#
# Function added to update a document each
# time a reprint is done. Index 'reprint' is updated with a 'I'
# and index 'log' is updated with a date and a counter of 001 (if the
# document has already been reprinted, the counter is added up by 001.
 
set -a
set -u
set -m
#set -x
 
##################
# 3 stmt's added #
# for debugging #
##################
#RANDOM=$$
#set -x
#exec 2> /usr/lpp/ars/bin/debug1.log.$RANDOM
 
RM=/bin/rm
SED=/bin/sed
 
OS=$(uname)
 
if [[ ${OS} = AIX ]] ; then
BASE_DIR=/usr/lpp/ars/bin
elif [[ (${OS} = HP-UX) || (${OS} = SunOS) ]] ; then
BASE_DIR=/opt/ondemand/bin
ARSPRT_HOSTNAME=
else
print "Cannot determine operating system"
exit 1
fi
 
#
# $1 - Printer Queue Name
# $2 - Copies
# $3 - Userid
# $4 - Application Group Name
# $5 - Application Name
# $6 - Application Print Options
# $7 - Filename to Print
 
#
# NOTE: It is up to this script to make sure the file is deleted.
# example( -r option on /bin/enq )
#
FILE=$7
OPTS_FILE=${FILE}.opts
NOTES_FILE=${FILE}.notes
if [[ -f ${OPTS_FILE} ]] ; then
DEL=1
PRT_OPTIONS="-o PASSTHRU=fax_file-${FILE}-"
#
# Since I am faxing, make sure messages are not produced.
# If debugging is needed, then this parameter should be blank.
#
#EXTRA_OPTIONS="-o MSGCOUNT=0"
EXTRA_OPTIONS="-o MSGCOUNT=0"
else
DEL=0
PRT_OPTIONS=
EXTRA_OPTIONS=
fi
 
TITLE=$(print "$3 $4 $5" | ${SED} 's/-/ /g')
 
if [[ ${OS} = AIX ]] ; then
/bin/enq -r -P "$1" -N $2 -T "${TITLE}" $6 ${EXTRA_OPTIONS} ${PRT_OPTIONS} ${FILE}
else
${BASE_DIR}/lprafp -p "$1" -s "${ARSPRT_HOSTNAME}" -o "COPIES=${2}" -o "JOBNAME=${TITLE}" -o "TITLE=${TITLE}" $6 ${EXTRA_OPTIONS} ${PRT_OPTIONS} ${FILE}
fi
 
RC=$?
 
if [[ ${RC} = 0 ]] ; then
if [[ ${OS} != AIX ]] ; then
${RM} -f ${FILE}
 
 
else
####################################
# Test if filename ends up with .0 #
# If not,skip around code to update#
# index. This prevents update of #
# same index several times as only #
# one .cntl file is created #
# when server print is made for #
# multiple documents and this #
# script is called one time for #
# each doc to print. #
####################################
ext=$7
ext=${ext##*.}
if [[ ${ext} = 0 ]] ; then
####################################
# Compute .cntl filname from #
# supplied parameter $7 #
####################################
fil=$7
mine=${fil%.*}.cntl
####################################
# Double check if .cntl file exist #
####################################
if test ! -f $mine
then echo "File $mine not found"
exit 1
fi
 
####################################
# Set static variables #
####################################
host=9.99.99.99
nohit=no
 
applgrp1=ICAlog
folder1=ICAlog
 
applgrp2=applg2
folder2=folder2
 
applgrp3=applg3
folder3=folder3
####################################
# Read info from .cntl file #
####################################
cat $mine |grep -v APPLICATION|while read a1 a2 a3 a4 a5 a6 a7 a8 a9
do
####################################
# Get the application group name #
####################################
applgrp=$a2
applgrp=${applgrp##*=}
####################################
# Set the folder name depending on #
# what the application group name #
# is #
####################################
if [[ ${applgrp} = ${applgrp1} ]]
then
folder=$folder1
else
if [[ ${applgrp} = ${applgrp2} ]]
then
folder=$folder2
else
if [[ ${applgrp} = ${applgrp3} ]]
then
folder=$folder3
####################################
# Not an application group we are #
# looking for. Set nohits=yes to #
# skip to remove the .cntl file #
####################################
else
nohit=yes
fi
fi
fi
####################################
# If nohit=no, get Account-number and#
# log info #
####################################
if [[ ${nohit} = no ]]
then
####################################
# Get Account Number #
####################################
account-number=$a4
account-number=${account-number##*=}
####################################
# Get log info. If first time, #
# then set count=001 and current #
# date #
####################################
log=$a8
log=${log##*=}
if [[ $log = "" ]]
then
log=001
####################################
# If not first time for reprint, #
# then add up old count by 1 #
####################################
else
let log=$log+001
typeset -Z3 log
fi
####################################
# Set date after log count #
####################################
datum=`date +%Y-%m-%d`
blank=" "
####################################
# Update this document with count #
# of reprints and current date #
####################################
arsdoc update -h $host -g $applgrp -f $folder -n log="$log$blank$datum" -n reprint=I -u admin -p ondemand -i "where account-number='$account-number'" -v
fi
####################################
# Done, remove the .cntl file #
####################################
done
rm $mine
fi
 
 
fi
else
(
if [[ ${OS} = AIX ]] ; then
echo /bin/enq -r -P "$1" -N $2 -T "${TITLE}" $6 ${EXTRA_OPTIONS} ${PRT_OPTIONS} ${FILE}
else
echo ${BASE_DIR}/lprafp -p "$1" -s "${ARSPRT_HOSTNAME}" -o "COPIES=${2}" -o "JOBNAME=${TITLE}" -o "TITLE=${TITLE}" $6 ${EXTRA_OPTIONS} ${PRT_OPTIONS} ${FILE}
fi
 
echo "$(date)-->OnDemand Failed Print File >${FILE}< to Queue >$1<"
) >/dev/console
exit ${RC}
fi
 
#
# If there is an options file, wait until the file has been
# printed before removing it.
#
if [[ ${DEL} != 0 ]] ; then
while(( 1 ))
do
if [[ -f "${FILE}" ]] ; then
sleep 30
else
${RM} -f ${OPTS_FILE} ${NOTES_FILE}
break
fi
done
fi
exit 0
11.5 Customized functions (Multiplatforms and z/OS only)
The user exits provide customized ways of performing tasks in Content Manager OnDemand. You can use it to customize logins, retrieve data from external locations, or send a notification when a document is loaded. Programming of the user exits is an IBM Lab Services offering; for more information, contact IBM Lab Services. You may also use the sample exit source code to write your own exits. In this section, we describe each of the sample exits that are provided in the standard Content Manager OnDemand installation to give you a better understanding of what they can do.
The sample source code for the Content Manager OnDemand user exits is provided for all the platforms. They are placed in the directories or libraries of Content Manager OnDemand that are listed in Table 11-1. These sample user exit modules provide a skeleton for you to program the exits.
Table 11-1 Exits and their initial locations
Module
Location
arsuload
arsuprep
arsuupdt
arsutbl
Content Manager OnDemand V8.5
Windows: C:Program FilesIBMOnDemand for Windowsinexits
AIX: /usr/lpp/ars/bin/exits
Solaris, HPUX, and Linux: /opt/ondemand/bin/exits
z/OS: /usr/lpp/ars/exits or ARS.V8R5M0.SARSINST
Content Manager OnDemand V9.0
Windows: C:Program FilesIBMOnDemand for WindowsV9.0inexits
AIX, Solaris, and HPUX: /opt/IBM/ondemand/V9.0/bin/exits
Linux and Linux on System z: /opt/ibm/ondemand/V9.0/ bin
z/OS: /usr/lpp/ars/V9R0M0/exits or ARS.V9R0M0.SARSINST
The header file provides information about how to turn on the user exits. If it is not specified in the header file, then place the compiled user exit program into the bin/exits directory of the Content Manager OnDemand installation root.
The source code must be compiled before use. For UNIX platforms, you can compile the source code by using the sample makefile that is provided. The makefile is in the same exits directory as the sample exits source code.
Table 11-2 provides the functions and usage of the user exit modules.
Table 11-2 User exits module
Module
Function
Usage
arsuload
LOADEXIT
To obtain load information for notification
arsuprep
PREPEXIT
To preprocess document data before document retrieval
arsuupdt
ARSUUPDT
To alter parameters when document data is being captured by ARSLOAD
arsutbl
TBLSPCRT
To customize creation of tablespace, tables, and indexes
11.5.1 The user exit header file (arscsxit.h)
Before you write the user exit, it is important to study the header file arscsxit.h. This file is in the same exits directory as the sample user exit source code. It contains the structure and function declarations for the customized Content Manager OnDemand user exits. There are also instructions about how to activate the user exits after it is compiled.
The first part of the header file is a declaration of all the structures and variables that are used. Example 11-9 shows some of the common structures that are used in the functions declarations.
Example 11-9 Common structure that is defined in the arscsxit.h header file
/*********************************************************************/
/* COMMON STRUCTURES */
/*********************************************************************/
#define ARCCSXIT_MAX_SRVR_MESSAGE_SIZE 1024
#if defined(AIX) || defined(HPUX) || defined(OS390) || defined(CICS)
#define ARCCSXIT_PATH_MAX 1023
#elif defined(LINUX)
#define ARCCSXIT_PATH_MAX 4096
#elif defined(SUNOS) || defined(__OS400__)
#define ARCCSXIT_PATH_MAX 1024
#elif defined(WIN32)
#define ARCCSXIT_PATH_MAX 260
#endif
typedef struct _ArcCSXitApplGroup
{
char *name;
ArcI32 agid;
char *agid_name;
} ArcCSXitApplGroup;
typedef struct _ArcCSXitApplGroupU
{
ArcChar *name;
ArcI32 agid;
ArcChar *agid_name;
} ArcCSXitApplGroupU;
typedef ArcU8 ArcCSXitDocType;
#define ARCCSXIT_DOC_TYPE_AFP (ArcCSXitDocType) 0x41
#define ARCCSXIT_DOC_TYPE_BMP (ArcCSXitDocType) 0x42
#define ARCCSXIT_DOC_TYPE_EMAIL (ArcCSXitDocType) 0x45
#define ARCCSXIT_DOC_TYPE_GIF (ArcCSXitDocType) 0x47
#define ARCCSXIT_DOC_TYPE_JFIF (ArcCSXitDocType) 0x4A
#define ARCCSXIT_DOC_TYPE_DJDE (ArcCSXitDocType) 0x4B
#define ARCCSXIT_DOC_TYPE_LINE (ArcCSXitDocType) 0x4C
#define ARCCSXIT_DOC_TYPE_META (ArcCSXitDocType) 0x4D
#define ARCCSXIT_DOC_TYPE_NONE (ArcCSXitDocType) 0x4E
#define ARCCSXIT_DOC_TYPE_ODDOC (ArcCSXitDocType) 0x4F
#define ARCCSXIT_DOC_TYPE_PCX (ArcCSXitDocType) 0x50
#define ARCCSXIT_DOC_TYPE_PDF (ArcCSXitDocType) 0x52
#define ARCCSXIT_DOC_TYPE_PNG (ArcCSXitDocType) 0x51
#define ARCCSXIT_DOC_TYPE_SCS (ArcCSXitDocType) 0x53
#define ARCCSXIT_DOC_TYPE_SCS_EXT (ArcCSXitDocType) 0x58
#define ARCCSXIT_DOC_TYPE_TIFF (ArcCSXitDocType) 0x54
#define ARCCSXIT_DOC_TYPE_USRDEF (ArcCSXitDocType) 0x55
typedef ArcU8 ArcCSXitDocFormat;
#define ARCCSXIT_DOC_FORMAT_FIXED (ArcCSXitDocFormat) 0x00
#define ARCCSXIT_DOC_FORMAT_VARIABLE (ArcCSXitDocFormat) 0x01
#define ARCCSXIT_DOC_FORMAT_STREAM (ArcCSXitDocFormat) 0x02
typedef ArcU8 ArcCSXitCarCtl;
#define ARCCSXIT_CC_ANSI (ArcCSXitCarCtl) 'A'
#define ARCCSXIT_CC_MACHINE (ArcCSXitCarCtl) 'M'
#define ARCCSXIT_CC_NONE (ArcCSXitCarCtl) 'N'
typedef ArcU8 ArcCSXitPrMode;
#define ARCCSXIT_PRMODE_NONE (ArcCSXitPrMode) 'N'
#define ARCCSXIT_PRMODE_SOSI1 (ArcCSXitPrMode) '1'
#define ARCCSXIT_PRMODE_SOSI2 (ArcCSXitPrMode) '2'
#define ARCCSXIT_PRMODE_SOSI3 (ArcCSXitPrMode) '3'
typedef struct _ArcCSXitAppl
{
char *name;
ArcI32 aid;
ArcCSXitDocType doc_type;
ArcCSXitDocFormat doc_fmt; /* Document Format for Linedata */
union
{
ArcI32 fixed; /* Fixed - Record Length */
char streamÝ17¨; /* Stream - Character Delimiters */
} u;
ArcU8 trc_present; /* 0 = no, 1 = yes */
ArcI32 line_count; /* Lines per page for line data */
ArcI32 code_page; /* Code Page for line data */
ArcCSXitCarCtl cc_type; /* CC type for line data */
ArcCSXitPrMode prmode; /* PRMode for line data */
} ArcCSXitAppl;
typedef struct _ArcCSXitApplU
{
ArcChar *name;
ArcI32 aid;
ArcCSXitDocType doc_type;
ArcCSXitDocFormat doc_fmt; /* Document Format for Linedata */
union
{
ArcI32 fixed; /* Fixed - Record Length */
ArcChar streamÝ17¨; /* Stream - Character Delimiters */
} u;
ArcU8 trc_present; /* 0 = no, 1 = yes */
ArcI32 line_count; /* Lines per page for line data */
ArcI32 code_page; /* Code Page for line data */
ArcCSXitCarCtl cc_type; /* CC type for line data */
ArcCSXitPrMode prmode; /* PRMode for line data */
} ArcCSXitApplU;
typedef ArcU8 ArcCSXitFieldType;
#define ARCCSXIT_FIELD_TYPE_BIGINT (ArcCSXitFieldType) 0x42
#define ARCCSXIT_FIELD_TYPE_DATE (ArcCSXitFieldType) 0x61
#define ARCCSXIT_FIELD_TYPE_DATETIME (ArcCSXitFieldType) 0x62
#define ARCCSXIT_FIELD_TYPE_DECFLOAT16 (ArcCSXitFieldType) 0x38
#define ARCCSXIT_FIELD_TYPE_DECFLOAT34 (ArcCSXitFieldType) 0x39
#define ARCCSXIT_FIELD_TYPE_DECIMAL (ArcCSXitFieldType) 0x44
#define ARCCSXIT_FIELD_TYPE_INTEGER (ArcCSXitFieldType) 0x49
#define ARCCSXIT_FIELD_TYPE_SMALLINT (ArcCSXitFieldType) 0x4E
#define ARCCSXIT_FIELD_TYPE_STRING (ArcCSXitFieldType) 0x53
typedef ArcU8 ArcCSXitFieldTypeQual;
#define ARCCSXIT_FIELD_TYPE_QUAL_BASE (ArcCSXitFieldTypeQual) 0x42
#define ARCCSXIT_FIELD_TYPE_QUAL_DATETIME (ArcCSXitFieldTypeQual) 0x43
#define ARCCSXIT_FIELD_TYPE_QUAL_DATE (ArcCSXitFieldTypeQual) 0x44
#define ARCCSXIT_FIELD_TYPE_QUAL_TIME (ArcCSXitFieldTypeQual) 0x54
#define ARCCSXIT_FIELD_TYPE_QUAL_TZ_DATETIME (ArcCSXitFieldTypeQual) 0x5A
typedef struct _ArcCSXitField
{
char *db_name;
ArcCSXitFieldType type;
ArcCSXitFieldTypeQual qual;
union
{
ArcI16 n;
ArcI32 i;
ArcI64 b;
double d;
char *str;
ArcDateTime dt;
ArcDecimal64 d64;
ArcDecimal128 d128;
} u;
} ArcCSXitField;
typedef struct _ArcCSXitFieldU
{
ArcChar *db_name;
ArcCSXitFieldType type;
ArcCSXitFieldTypeQual qual;
union
{
ArcI16 n;
ArcI32 i;
ArcI64 b;
double d;
ArcChar *str;
ArcDateTime dt;
ArcDecimal64 d64;
ArcDecimal128 d128;
} u;
} ArcCSXitFieldU;
typedef struct _ArcCSXitDocFields
{
ArcI32 flds_num;
ArcCSXitField *flds;
} ArcCSXitDocFields;
#define ARCCSXIT_DOCNAME_SIZE 11
typedef struct _ArcCSXitDocHandle
{
char nameÝARCCSXIT_DOCNAME_SIZE + 1¨;
ArcU32 doc_off;
ArcU32 doc_len;
ArcU32 comp_off;
ArcU32 comp_len;
} ArcCSXitDocHandle;
typedef struct _ArcCSXitDoc
{
ArcCSXitDocFields doc_flds;
ArcCSXitDocHandle doc_hndl;
} ArcCSXitDoc;
From the previous example, the ArcCSXitApplGroup structure consists of the application group name, the application group identifier (agid), and the AGID name (agid_name). This information is important because it indicates the input to the functions. There are structures that are specific to a function itself that are also included in the header file.
In the following sections, we examine each exit and describe its usage
and functionality.
11.5.2 Load exit
The load exit is used to send a notification after a document is loaded. The header file in Example 11-10 shows the information that can be incorporated into the notification message.
Example 11-10 Header file of the load exit
/**********************************************************************/
/* LOADEXIT - Load Exit */
/* */
/* To activate the load exit, the arsuload dll must exist in the */
/* OnDemand exits installation directory. */
/* */
/* INPUT: load */
/* */
/* OUTPUT: */
/* None */
/* */
/* RETURN_CODE: */
/* 0 -> Successful */
/* Otherwise -> Failed */
/* */
/**********************************************************************/
typedef struct _ArsCSXitLoadExit
{
char *hostname; /* OnDemand Library Server Hostname */
char *load_id; /* Load Id */
ArcU32 deprecated; /* was bytes. Use report_bytes */
ArcU32 res_bytes; /* Number of resource bytes stored */
ArcCSXitApplGroup *appl_grp; /* Application Group Info */
ArcCSXitAppl *appl; /* Application Info */
char *file; /* File containing all rows */
char *user_def; /* User Specified string to load */
ArcCSXitField *reference; /* Reference column defined for ODF */
char *file_l; /* File containg rows in non-UTF8 */
ArcU32 cp; /* codepage file_l is in */
void **hndl; /* pointer to anchor for arsuload */
char ColDelim; /* Character used to delimit columns*/
ArcI64 report_bytes;/* Number of bytes in report */
char *instance; /* OD Instance name */
} ArsCSXitLoadExit;
ArcI32
ARSCSXIT_EXPORT
ARSCSXIT_API
LOADEXIT( ArsCSXitLoadExit *load );
You can use the sample exits program to insert the action that you prefer. The input to the program is in the structure ArsCSXitLoadExit. This structure contains the load information, such as the load identifier and the application group name. Based on the load information, you decide whether to send a notification, to whom to send the notification, and the type of information you want to provide when loading is successful.
Activating the load exit
To activate the exits, place the compiled exit program arsuload in to the bin/exits directory of the Content Manager OnDemand installation root.
Client retrieval preview exit
The client retrieval preview user exit allows for the modification of document data before the data is presented to a client. It is called during the retrieval of
a document.
You can use the client retrieval preview exit to add, remove, or reformat data before the document is presented to the client. For example:
You can remove pages from the document, such as banner pages, title pages, or all pages except for the summary page.
You can remove specific words, columns of data, or other information from the document, that is, you omit (“white out”) sensitive information, such as salaries, social security numbers, and birth dates.
You can add information to the document, for example, a summary page, data analysis information, and Confidential or Copy statements.
You can reformat data that is contained in the document. For example, you can reorder the columns of data.
The client retrieval preview exit point might be enabled for specific applications. However, to enable the client retrieval preview exit for a specific application, ensure that the Use Preview Exit option is selected on the Miscellaneous Options page of the application.
The input to the exit program is captured when the user tries to retrieve the document. Based on the input, such as application group name and the indexes, you can then use your program to create an output file with the name from pOutFileName.
Example 11-11 shows the header file of the client retrieval preview exit.
Example 11-11 Header file of client retrieval preview exit
/**********************************************************************/
/* PREPEXIT - Client Retrieval Preview Exit */
/* */
/* This exit is used to modify the contents of a document prior */
/* retrieving the document */
/* */
/* INPUT: */
/* pInFileName */
/* pOutFileName */
/* pUserParms */
/* pApplGrp */
/* pAppl */
/* pDoc */
/* */
/* OUTPUT: */
/* */
/* RETURN_CODE: */
/* 0 -> Successful */
/* Otherwise -> Failed */
/* */
/**********************************************************************/
typedef struct _ArsCSXitPrepExit
{
char *pUserid; /* Logged on userid */
char *pInFileName; /* File name for document data */
char OutFileName[ARCCSXIT_PATH_MAX + 1];
/* File name for modified data */
char *pUserParms; /* User defined parms from appl */
ArcCSXitApplGroup *pApplGrp; /* Appl Grp info */
ArcCSXitAppl *pAppl; /* Application info */
ArcCSXitDoc *pDoc; /* Doc handle, field info */
char *instance; /* OD Instance name */
} ArsCSXitPrepExit;
ArcI32
ARSCSXIT_EXPORT
ARSCSXIT_API
PREPEXIT( ArsCSXitPrepExit *prep );
For example, you can arrange it so that when a user retrieves a document from a particular application group, you can check the name of the account number (the indexes from the Doc handle) and place a watermark for that document. When the document is retrieved by the user, the user sees the document with
the watermark.
Activating the client retrieval preview exit
To activate the client retrieval preview exit, select the Use Preview Exit option on the Miscellaneous Options page of an application and place the exit in the bin/exits directory of the Content Manager OnDemand installation root. When the option is selected, the user-written program is called any time that a request is made to retrieve a document.
Any information that is specified in the Parameters field is passed to the user-written program. Place the arsuprep program in the bin/exits directory.
The client retrieval preview user exit can be enabled for all data types, except
for None.
For more information, see IBM Content Manager OnDemand for Multiplatforms - Installation and Configuration Guide, SC18-9232.
11.5.3 Report specifications archive definition exit
The Content Manager OnDemand report specifications archive definition exit allows an installation to change some of the parameters that are used by Content Manager OnDemand when document data is loaded by the ARSLOAD program. ARSUUPDT is a DLL module that is written in the C programming language.
The first call modifies the names process for parameters, such as application group, application, object server, storage node, DB field date format, and DB field name. The second call modifies the indexing parameters and input file parameters. Example 11-12 shows the header file of the Report specifications archive definition exit.
Example 11-12 Header file of the report specification archive definition exit
/**********************************************************************/
/* UPDTEXIT - Report Definition Update Exit */
/* */
/* This exit is for specialized applications and is not normally */
/* used. */
/* */
/* INPUT: */
/* pFileName */
/* Function */
/* ApplGrpName */
/* ApplName */
/* ObjServer */
/* StorageNode */
/* pJES */
/* IndexerParms */
/* CCType */
/* LRECL */
/* RECFM */
/* Delim */
/* instance */
/* */
/* OUTPUT: */
/* ApplGrpName */
/* ApplName */
/* ObjServer */
/* StorageNode */
/* IndexerParms */
/* CCType */
/* LRECL */
/* RECFM */
/* UpdateAppl */
/* Delim */
/* DbFieldName */
/* DbFieldDateFormat */
/* */
/* RETURN_CODE: */
/* 0 -> Successful */
/* Otherwise -> Failed */
/* */
/**********************************************************************/
#if defined(OS390)
typedef struct _ArsCSXitUpdtExit_JES
{
void *JES_SSS2p; /* pointer to SSS2 (SAPI SSOB ext) */
char JES_DDÝ8¨; /* DD name allocated to spool file */
} ArsCSXitUpdtExit_JES;
#endif
typedef struct _ArsCSXitUpdtExit
{
char *pFileName;
ArcI32 Function;
char ApplGrpNameÝARCCSXIT_MAX_NAME_SIZE + 1¨;
char ApplNameÝARCCSXIT_MAX_NAME_SIZE + 1¨;
char ObjServerÝARCCSXIT_MAX_SERVER_SIZE + 1¨;
char StorageNodeÝARCCSXIT_MAX_NAME_SIZE + 1¨;
void *pJES;
char IndexerParmsÝARCCSXIT_MAX_INDEXER_SIZE + 1¨;
ArcCSXitCarCtl CCType;
ArcI32 LRECL;
ArcCSXitDocFormat RECFM;
ArcI32 UpdateAppl;
char DelimÝARCCSXIT_MAX_DELIMITER_SIZE + 1¨;
char *instance;
char DbFieldNameÝARCCSXIT_MAX_DBCOL_NAME_SIZE + 1¨;
char DbFieldDateFormatÝARCCSXIT_MAX_DATEFMT_SIZE + 1¨;
} ArsCSXitUpdtExit;
typedef struct _ArsCSXitUpdtExitU
{
ArcChar *pFileName;
ArcI32 Function;
ArcChar ApplGrpNameÝARCCSXIT_MAX_NAME_SIZE + 1¨;
ArcChar ApplNameÝARCCSXIT_MAX_NAME_SIZE + 1¨;
ArcChar ObjServerÝARCCSXIT_MAX_SERVER_SIZE + 1¨;
ArcChar StorageNodeÝARCCSXIT_MAX_NAME_SIZE + 1¨;
void *pJES;
ArcChar IndexerParmsÝARCCSXIT_MAX_INDEXER_SIZE + 1¨;
ArcCSXitCarCtl CCType;
ArcI32 LRECL;
ArcCSXitDocFormat RECFM;
ArcI32 UpdateAppl;
ArcChar DelimÝARCCSXIT_MAX_DELIMITER_SIZE + 1¨;
ArcChar *instance;
ArcChar DbFieldNameÝARCCSXIT_MAX_DBCOL_NAME_SIZE + 1¨;
ArcChar DbFieldDateFormatÝARCCSXIT_MAX_DATEFMT_SIZE + 1¨;
} ArsCSXitUpdtExitU;
ArcI32
ARSCSXIT_EXPORT
ARSCSXIT_API
UPDTEXIT( ArsCSXitUpdtExit *updt );
Activating the report specifications archive definition exit
The report specifications archive definition exit is implemented by a single DLL, ARSUUPDT. ARSUUPDT is a DLL module that is written in the C programming language. The samples that are shipped (ARSUUPDT and ARSUUPDC) initialize the ARSUUPDA structure and call the ARSUUPDX ARS.RSADUPDT exit driver.
The ARSUUPDT DLL invokes module ARSUUPDX. Module ARSUUPDX interfaces with the MVS Dynamic Exit Facility to perform the following actions:
Define the logical exit point name: ARS.RSADUPDT.
Route control to a set of MVS associated exit routines and process the results of their execution.
Module ARSUUPDZ is implemented as an MVS associated dynamic exit routine. An exit routine is eligible for execution after it becomes associated with the logical exit point. The MVS Dynamic Exit Facility provides several methods for performing this association.
When the exit routine is assembled and link-edited to a library, it must be associated with the exit in one of two ways:
Use the exit statement in PROGXX parmlib member. For more information about the PROGXX parmlib member, see z/OS MVS Initialization and Tuning Reference, SA22-7592.
Use the SETPROG EXIT operator command. For more information about the SETPROG EXIT command, see z/OS MVS System Commands, SA22-7627.
Use the following command to activate the exit routine and associate ARSUUPDZ with the logical exit point name. (The example assumes that ARSUUPDZ can be found in the LPA or an LNKLST dataset.)
SETPROG EXIT,ADD,EXITNAME=ARS.RSADUPDT,MODNAME=ARSUUPDZ
Enabling the report specifications archive definition exit
To enable the exit in Content Manager OnDemand, run the ARSLOAD program with the -E parameter.
 
Note: The -E parameter must be specified in uppercase.
For more information about the report specifications archive definition exit routines, see Chapter 40, “Report specifications archive definition exit”, in Content Manager OnDemand for z/OS Configuration Guide, SC19-3363.
11.5.4 Tablespace creation exit
The Content Manager OnDemand tablespace creation exit allows an installation to take action when Content Manager OnDemand creates a tablespace, table, or index tables that are used to store application index data. The exit is not called for the Content Manager OnDemand system tables. The tablespace creation exit is used to modify the way Content Manager OnDemand creates tablespaces, tables, or indexes. For table and index creation, the installation can alter the SQL that is used to create the table or index.
You can also use this exit to perform other actions during a tablespace creation. This is useful if you must change default parameters for the tablespace, the table, or the indexes. The changes affect only new creations. Example 11-13 shows the header file of the tablespace creation exit.
Example 11-13 Header file for the tablespace create exit
/**********************************************************************/
/* TBLSPCRT - Tablespace Create Exit */
/* */
/* To activate the tablespace creation exit, set the following */
/* variable in the appropriate OnDemand instance ars.cfg file: */
/* */
/* ARS_DB_TABLESPACE_USEREXIT=<absolute_dll_path_name> */
/* */
/* INPUT: appl_grp */
/* tblsp_name */
/* table_name */
/* idx_name */
/* sql (allocated with 16384 bytes) */
/* action */
/* instance */
/* */
/* OUTPUT: */
/* */
/* 1) OnDemand will invoke the exit with action == 1 */
/* so that the exit can create the tablespace (tblsp_name) */
/* using (sql) */
/* *created -> 0 exit did not create the tablespace, */
/* OnDemand needs to create the tablespace */
/* using (sql), which can be left unchanged */
/* or modified by the exit */
/* *created -> 1 exit created the tablespace */
/* */
/* 2) OnDemand will then invoke the exit with action == 2 */
/* so that the exit can create the table (table_name) */
/* inside of the tablespace (tblsp_name) using (sql) */
/* *created -> 0 exit did not create the table, */
/* OnDemand needs to create the table */
/* using (sql), which can be left unchanged */
/* or modified by the exit */
/* *created -> 1 exit created the table */
/* */
/* 3) OnDemand will then invoke the exit with action == 3 */
/* so that the exit can create the table indexes (idx_name) */
/* inside of the tablespace (tblsp_name) for table */
/* (table_name) using (sql). This will be invoked based */
/* on the number of indexes to create for the appl_grp */
/* *created -> 0 exit did not create the index, */
/* OnDemand needs to create the index */
/* using (sql), which can be left unchanged */
/* or modified by the exit */
/* *created -> 1 exit created the index */
/* */
/* 4) OnDemand will then invoke the exit with action == 4 */
/* so that the exit can perform any additional work */
/* *created -> Is not used */
/* sql -> If sql is not an empty string, OnDemand */
/* will issue (sql) to the database */
/* */
/* If ARS_DB_TABLESPACE_USEREXIT_EXTRA=1 is defined in */
/* ars.cfg, then the following actions will also be invoked */
/* when OnDemand needs to do further actions: */
/* */
/* 5) OnDemand will invoke the exit with action == 5 */
/* so that the exit can drop the tablespace (tblsp_name) */
/* using (sql) */
/* *created -> 0 exit did not drop the tablespace, */
/* OnDemand needs to drop the tablespace */
/* using (sql), which can be left unchanged */
/* or modified by the exit */
/* *created -> 1 exit dropped the tablespace */
/* */
/* 6) OnDemand will invoke the exit with action == 6 */
/* so that the exit can drop the table (table_name) */
/* using (sql) when OnDemand needs to drop a table */
/* *created -> 0 exit did not drop the table, */
/* OnDemand needs to drop the table */
/* using (sql), which can be left unchanged */
/* or modified by the exit */
/* *created -> 1 exit dropped the table */
/* */
/* 7) OnDemand will invoke the exit with action == 7 */
/* so that the exit can drop the index (idx_name) */
/* using (sql) */
/* *created -> 0 exit did not drop the index, */
/* OnDemand needs to drop the index */
/* using (sql), which can be left unchanged */
/* or modified by the exit */
/* *created -> 1 exit dropped the index */
/* */
/* 8) OnDemand will invoke the exit with action == 8 */
/* so that the exit can alter the table (table_name) */
/* using (sql) */
/* *created -> 0 exit did not alter the table, */
/* OnDemand needs to alter the table */
/* using (sql), which can be left unchanged */
/* or modified by the exit */
/* *created -> 1 exit altered the table */
/* */
/* RETURN_CODE: */
/* 0 -> Successful */
/* Otherwise -> Failed */
/* */
/**********************************************************************/
ArcI32
ARSCSXIT_EXPORT
ARSCSXIT_API
TBLSPCRT( ArcCSXitApplGroup *appl_grp,
char *tblsp_name,
char *table_name,
char *idx_name,
char *sql,
ArcI32 action,
ArcI32 *created,
char *instance
);
You can use SQL code to customize the following actions:
Creating a tablespace
Creating a table
Creating an index
Other additional action
If you do not customize the action, Content Manager OnDemand uses
the defaults.
Example 11-14 shows a sample program flow.
Example 11-14 Sample program flow
Action 1
Is there a need to customize the creation of the tablespace?
If yes
create the tablespace
return( created = 1)
Else
OnDemand create the tablespace
return( created = 0)
 
Action 2
Is there a need to customize the creation of the table?
If yes
create the table (in the tablespace)
return( created = 1 )
Else
OnDemand create the table
return( created = 0 )
 
Action 3
Is there a need to customize the creation of the indexes?
If yes
create the indexes
return( created = 1 )
Else
OnDemand create the indexes
return( created = 0 )
 
Action 4
Final call, is there additional work, clean up or update on parameters?
If yes
perform the additional action.
return( created = not used )
Else
OnDemand do nothing
return( created = not used )
Activating the tablespace creation exit
The exit is turned on by setting the following parameter in the ARS.CFG file, which is in the config directory of the Content Manager OnDemand installation root.
The following statement must exist in the ARS.CFG file that is associated with the instance so that the ARSUTBL DLL can be invoked:
ARS_DB_TABLESPACE_USEREXIT=absolute path name
Where “absolute path name = ... /bin/exits/arsutbl”
For more information about the tablespace creation exit, see IBM Content Manager OnDemand for Multiplatforms - Installation and Configuration Guide, SC18-9232.
11.5.5 ARSYSPIN and sample APKACIF exit on z/OS
The JES Spool Capture facility ARSYSPIN and the sample APKACIF exit are provided on z/OS. ARSYSPIN provides a means to collect and consolidate the JES spool (SYSOUT) dataset into one or more files so they can be archived by Content Manager OnDemand. The facility runs as a started task in its own address space. A control statement file is used to provide ARSYSPIN parameters. These parameters specify JES Spool file selection criteria (for example, the sysout class that is taken for capture output) and other
operational characteristics.
ARSYSPIN creates an intermediate output file that contains one or more spool files from one or more jobs. The intermediate output file is indexed and stored in Content Manager OnDemand using the ARSLOAD program. ARSYSPIN invokes ARSLOAD when sufficient data is captured in the intermediate output file. ARSLOAD calls the indexer program (APKACIF) to extract the index values from the data and store them in an index file. ARSLOAD adds these index values to the database and stores the data object. If you want, you can use ARSYSPIN exits to augment the data stream.
In particular, the ARSYSPIN Input Exit (UX03) and Separator Exit (UX06) provide substantially more information about the job that produced the spool file being processed than what is available at the time when APKACIF (or another indexer program) is driven by Content Manager OnDemand. In addition, the processing impact of driving ARSYSPIN exit routines is lower than that associated with indexer exit routines, ARSSPVIN.
ARSSPVIN is a sample APKACIF input exit that is provided with ARSYSPIN to introduce additional index values into the data stream, using a “trailer” record. Trailer records are inserted at the end of the JESMSGLG data, and reflect the highest severity condition (this may be a step completion code, an ABEND code, or other type of problem, such as a JCL error) that is observed in messages that are contained within these spool files.
Special considerations for APKACIF exits written in COBOL
The provided sample exit is written as a COBOL main program. To prevent the IBM Language Environment® from creating and destroying the COBOL runtime environment each time ARSSPVIN is called, a CEEUOPT CSECT must be assembled and link-edited with the COBOL object code.
Constructing a CEEUOPT CSECT is documented in z/OS Language Environment Customization, SA22-7564. A sample CEEUOPT CSECT is included in dataset CEE.SCEESAMP(CEEUOPT). You can use this sample as a model, but you must be sure that the following option is specified:
RTEREUS=(ON)
CEEUOPT CSECT must be assembled and link-edited with the COBOL object code. In addition, you must be sure that the resulting module is link-edited as NOT RE-ENTRANT and NOT REUSEABLE. This is required to allow the local variables within the COBOL exit code to retain their values. This exit is invoked several times during an ACIF run. The sample source code can be found in the SARSINST library member ARSSPVIN. Example 11-15 shows a sample CEEUOPT CSECT.
Example 11-15 CEEUOPT CSECT
CEEUOPT CSECT ,
CEEUOPT AMODE ANY
CEEUOPT RMODE ANY
CEEXOPT
ABPERC=(NONE), +
ABTERMENC=(ABEND), +
AIXBLD=(OFF), +
ALL31=(ON), +
ANYHEAP=(16K, 8K, ANYWHERE, FREE) +
BELOWHEAP=(8K, 4K, FREE), +
CBLOPTS=(ON), +
CBLPSHPOP=(ON), +
CBLQDA=(OFF), +
CEEDUMP=(60,SYSOUT=*,FREE=END,SPIN=UNALLOC), +
CHECK=(ON), +
COUNTRY=(US), +
DEBUG=(OFF), +
DEPTHCONDLMT=(10), +
DYNDUMP=(*USERID,NODYNAMIC,TDUMP), +
ENVAR=(’’), +
ERRCOUNT=(0), +
ERRUNIT=(6), +
FILEHIST=(ON), +
FILETAG=(NOATOCVT,NOAUTOTAG), +
HEAP=(32K,32K,ANYWHERE,KEEP,8K,4K), +
HEAPCHK=(OFF,1,0,0,0), +
HEAPPOOLS=(OFF,8,10,32,10,128,10,156,10,1024,10,2048, +
10,0,10,0,10,0,10,0,10,0,10,0,10), +
INFOMSGFILTER=(OFF,,,,), +
INQPCOPN=(ON), +
INTERRUPT=(OFF), +
LIBSTACK=(4K,4K,FREE), +
MSGFILE=(SYSOUT,FBA,121,0,NOENQ), +
MSGQ=(15), +
NATLANG=(ENU), +
NOAUTOTASK=, +
NOTEST=(ALL,*,PROMPT,INSPPREF), +
NOUSRHDLR=(’’), +
OCSTATUS=(ON), +
PC=(OFF), +
PLITASKCOUNT=(20), +
POSIX=(OFF), +
PROFILE=(OFF,’’), +
PRTUNIT=(6), +
PUNUNIT=(7), +
RDRUNIT=(5), +
RECPAD=(OFF), +
RPTOPTS=(OFF), +
RPTSTG=(OFF), +
RTEREUS=(ON), + <====ATTENTION
SIMVRD=(OFF), +
STACK=(128K,128K,ANYWHERE,KEEP,512K,128K), +
STORAGE=(NONE,NONE,NONE,OK), +
TERMTHDACT=(TRACE,,96), +
THREADHEAP=(4K,4K,ANYWHERE,KEEP), +
THREADSTACK=(OFF,4K,4K,ANYWHERE,KEEP,128K,128K), +
TRACE=(OFF,4KDUMP,LE=0), +
TRAP=(ON,SPIE), +
UPSI=(00000000), +
VCTRSAVE=(OFF), +
XPLINK=(OFF), +
XUFLOW=(AUTO) +
END,
Activating the exit
To activate the exit, you must add the executable file to a loadlib in the Steplib (ARSLOAD) procedure. You must also supply the ACIF control statement INPEXIT = ARSSPVIN to the indexing parameters. You can do this task when you add an application in the Indexer Information window.
Complete the following steps:
1. Open the Add an Application window and click the Indexer Information tab, as shown in Figure 11-3.
Figure 11-3 Indexer Information tab
2. Click Modify.
3. Click the Exit Information tab, as shown in Figure 11-4.
Figure 11-4 Specify Load Module Name in the Exit Information tab
4. In the Input Records field, enter the name of the exit.
5. Click OK.
The exit is added to your indexing parameters.
Editing the indexer parameters
Figure 11-5 shows the Edit Indexer Parameters window.
Figure 11-5 Edit Exit Information
If you have an existing application, edit your indexing parameters and add the following line, as in shown in Figure 11-5:
INPEXIT=ARSSPVIN
For more information about activating this exit, see Content Manager OnDemand for z/OS Version 9.0 Administration Guide, SC19-3364.
 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset