Wednesday, April 8, 2020

System Reply List and using SQL to view the list

using system reply list

My original plan was to answer a question about the best way to retrieve the data from the system reply list on a particular IBM i partition. Before I wrote that post I asked my colleagues whether they knew about reply lists and had they used them? From their reactions I think I need to discuss what the system reply list is, and include the answer to my question within this post.

What the system reply list allows me to create a list of entries that will handle inquiry messages. On my travels I seen a few sites that use this feature, while most do not.

Reply lists have been around forever, all the way back to the days of the AS400. From what I remembered while creating the examples for this post I don't think anything has changed since I first played with them.

I wanted to have a simple example so I chose to work with the error received when a physical file is full, CPA5305.

When I create a physical file I can give the initial number of records the file will contain, when the file is full the number of records to increase it by, and the number of times to increase the number of records before alerting the operator.

Member size:
  Initial number of records  . .   10000      
  Increment number of records  .   1000  
  Maximum increments . . . . . .   3     

When I create physical files I use the size of *NOMAX. This does not mean that the file has enormous amounts of unused space. There is just no limit to the number of records that can be added to the file, well, until the file gets to the maximum size that a physical file can be.

Member size:
  Initial number of records  . .   *NOMAX     
  Increment number of records  .         
  Maximum increments . . . . . .         

But here in this example, I want a small number of records allocated to my test file:

CRTPF FILE(QTEMP/TESTFILE) RCDLEN(1) SIZE(5 1 1)

Looking back at this I have no idea why I chose the file to have a size of five records. I could have just said one instead. The first "1" is the number of times I will increase the size of the file. The second "1" is the number of records the file is increased by.

I can use the Display File Description command, DSPFD, so see how many records have been allocated to this file, etc.:

Member size
  Initial number of records . . . :         5
  Increment number of records . . :    1
  Maximum number of increments  . :    1
Record capacity . . . . . . . . . :         6

Now I can add records to the file. I am just going to use the Update Data command, UPDDTA, this command generated a temporary program for me that I can use to enter data into the file. As I am only going to be playing with less than 10 records I did not see the point in writing my own program.

UPDDTA FILE(QTEMP/TESTFILE)


WORK WITH DATA IN A FILE              Mode . . . . :   ENTRY
Format . . . . :   TESTFILE           File . . . . :   TESTFILE


TESTFILE:  

I can enter the following into the single character entry field: 1, 2, 3, 4, 5.

When I add the sixth record, 6, I see the following entry in my job's job log:

Size of member TESTFILE increased 1 increments.

Now for the seventh, 7, when I press Enter I get the following message at the bottom of the screen:

Waiting for reply to message on message queue QSYSOPR.

When I look in the QSYSOPR message queue I see the following error:

Record not added. Member TESTFILE is full. (C I 9999)

I can prompt the message and see that the message id is CPA5305. I will be needing that below to add to the reply list.

Before I add anything to the reply list let me display the list using SQL:

01  SELECT SEQUENCE_NUMBER AS "Seq",
02         MESSAGE_ID AS "Msg Id",
03         MESSAGE_REPLY AS "Reply",
04         COMPARISON_DATA AS "Comp Dta",
05         COMPARISON_DATA_OFFSET AS "Offset",
06         DUMP_JOB AS "Dump"
07  FROM QSYS2.REPLY_LIST_INFO

This statement lists all of the columns from the REPLY_LIST_INFO view. For my own use I used the standard:

SELECT * FROM QSYS2.REPLY_LIST_INFO

When the results are returned with the default column headings the results are too wide to fit on this page. This is why I used short names for all the columns. The results are:

Seq  Msg Id    Reply  Comp Dta  Offset  Dump
----  -------  -----  --------  ------  ----
   1  CPA3312    G    -         -        NO
   5  CPA33B2    I    -         -        NO
  10  CPA0700    D    -         -        YES
  20  RPG0000    D    -         -        YES
  30  CBE0000    D    -         -        YES
  40  PLI0000    D    -         -        YES

The same results can be seen using the Work with Reply List Entries command, WRKRPYLE.

SEQUENCE_NUMBER: The operating system starts with the lowest sequence and stops when it finds the first entry that matches the message id.

MESSAGE_ID: This can either be a specific message id or can be for a range. For example CPA0700 includes all message ids from CPA0700 to CA0799. RPG0000 includes all message ids from RPG0000 to RPG9999.

MESSAGE_REPLY: The reply the message is answered with.

COMPARISON_DATA: This can be used to limit the response to, say, just one file. I will give an example below.

COMPARISON_DATA_OFFSET: Used with the COMPARISON_DATA. Where in the data sent to the message is the data given in the COMPARISON_DATA.

DUMP_JOB: A dump of the job log is generated, the same as using the following CL command:

DSPJOB OUTPUT(*PRINT)

I can add a reply list entry for the message id I encountered earlier using the Add Reply List Entry command, ADDRPYLE:

ADDRPYLE SEQNBR(99) MSGID(CPA5305) RPY(9999)

That statement means:

  • Add at sequence 99
  • For message id CPA5305
  • Reply of 9999

When I pressed Enter the entry was added, see below:

Seq  Msg Id    Reply  Comp Dta  Offset  Dump
----  -------  -----  --------  ------  ----
   1  CPA3312    G    -         -        NO
   5  CPA33B2    I    -         -        NO
  10  CPA0700    D    -         -        YES
  20  RPG0000    D    -         -        YES
  30  CBE0000    D    -         -        YES
  40  PLI0000    D    -         -        YES
  99  CPA5305  9999   -         -        NO

Before my job will use the reply list I need to tell it to do so using the INQMSGRPY(*SYSRPYL) parameter. This can be used with the following commands:

SBMJOB ... INQMSGRPY(*SYSRPYL)
CHGJOB INQMSGRPY(*SYSRPYL)
CRTJOBD ... INQMSGRPY(*SYSRPYL) 
CHGJOBD ... INQMSGRPY(*SYSRPYL)

For these examples I am going to use the Change Job command, CHGJOB, and change my job to use the system reply list:

CHGJOB INQMSGRPY(*SYSRPYL)

I can then use the Display Job command, DSPJOB, to show that my job is now using the reply list. Take option 2 from the "Display Job" menu, and page down until I see:

           Display Job Definition Attributes
Job:  QPADEV0002    User:  SIMON    Number: 256477


Inquiry message reply . . .. . . . . . :   *SYSRPYL

As my job is using the reply list I cannot attempt to add the seventh record to the file using the UPDDTA command. When I enter "7" there is a pause and no error. I can use the DSPFD command to look at the number of records in the file and I see:

Member size
  Initial number of records . . . :         5
  Increment number of records . . :    1
  Maximum number of increments  . :    1
  Current number of records . . . :     10000 
Record capacity . . . . . . . . . :     10005

The size has been increased from the original 5 records that were created when I created the file + 1 for the allowed increment for the 6th record + 9,999 records the reply list had to increment the size of the file by.

This reply list entry will apply to every file that gets full. Perhaps I only want to increase the size TESTFILE only, and have all others error when they are full. This is where the Comparison Data and Comparison Data Offset are used. I am going to change the reply list entry I added using the Change Reply List Entry command, CHGRPYLE:

CHGRPYLE SEQNBR(99) MSGID(CPA5305) CMPDTA('TESTFILE' 1)

The interesting part is the CMPDTA parameter. Here I am saying that when the error CPA5305 occurs when the data is passed from the job to the error the string "TESTFILE" must occur starting at position 1. If it does not then reply list entry is not executed.

Having changed the entry I can use my SQL statement to view the change:

SELECT SEQUENCE_NUMBER AS "Seq",
       MESSAGE_ID AS "Msg Id",
       MESSAGE_REPLY AS "Reply",
       COMPARISON_DATA AS "Comp Dta",
       COMPARISON_DATA_OFFSET AS "Offset",
       DUMP_JOB AS "Dump"
FROM QSYS2.REPLY_LIST_INFO


Seq  Msg Id   Reply  Comp Dta  Offset  Dump
----  -------  -----  --------  ------  ----
   1  CPA3312    G    -         -        NO
   5  CPA33B2    I    -         -        NO
  10  CPA0700    D    -         -        YES
  20  RPG0000    D    -         -        YES
  30  CBE0000    D    -         -        YES
  40  PLI0000    D    -         -        YES
  99  CPA5305  9999   TESTFILE  1        NO

Let me recreate TESTFILE so I can test again:

DLTF QTEMP/TESTFILE

CRTPF FILE(QTEMP/TESTFILE) RCDLEN(1) SIZE(5 1 1)

Now I can add records to the file using UPDDTA command: 1, 2, 3, 4, 5, 6 the file is increased by one record to accommodate this entry, 7 there is no CPA5305 error and the file is increased by 9,999 records.

I need to create another file to test with. I cannot call it TESTFILE2 as the comparison data for sequence 99 is checking for "TESTFILE" starting at position one, which would mean that TESTFILE2 would use the reply list entry.

Therefore, my second test file is FILE2. I create it in the same way I did TESTFILE:

CRTPF FILE(QTEMP/FILE2) RCDLEN(1) SIZE(5 1 1)

I use the same command to add records to FILE2 that I used with TESTFILE.

UPDDTA FILE(QTEMP/FILE2)

I add six records without error, when I tried to add the seventh I receive the CPA5305 error:

Record not added. Member FILE2 is full. (C I 9999)

Which proves that reply list entry sequence 99 will only be used for files that start with "TESTFILE".

As I have finished playing with reply lists it is only right that I remove the entry I created:

RMVRPYLE SEQNBR(99)

I have known some sites over use reply lists, trying to enter every possible error code there is with the response they desire. In my opinion this approach is dangerous as you cannot decide how to handle an error in a program by program basis. The same message reply is sent every time. I believe that a well placed MONSMG command or Monitor operation code is a better way to handle the situation that caused the error.

 

You can learn more about this from the IBM website:

 

This article was written for IBM i 7.4, and should work for earlier releases too.

2 comments:

  1. This is awesome. I am working on a program that will benefit from this!

    ReplyDelete
  2. Very helpful and well explained blog.

    ReplyDelete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.