# Compaq ACMS for OpenVMS
Writing Server Procedures

Previous | Contents | Index

# Chapter 14
Implementation Details of the Sample Application

The APPC/LU6.2 programming interface enables Compaq OpenVMS users to connect to remote third-party computers, providing the connectivity that enables both the other vendor's computer and Compaq computers to transparently exchange data and share resources.

This chapter contains a sample program that shows how ACMS, by using APPC/LU6.2 as its interconnectivity programming interface, can communicate with a remote IBM host computer's application program (in particular, an IBM CICS transaction processing application). The sample program is based on the Personnel Application example provided in Compaq ACMS for OpenVMS Getting Started.

Because the purpose of the sample is to demonstrate interconnectivity, it provides a single inquiry option on the ACMS menu. Real ACMS applications, however, are not limited to inquiry options; they can also write, modify, and delete data on IBM and other vendor databases.

# 14.1 Execution Flow of the Sample Task

Figure 14-1 shows how the task definition in this sample controls the flow of work between the ACMS user and the IBM database. (The task definition runs after the user selects the inquiry option from the ACMS menu.)

Figure 14-1 Execution Flow of the Sample Task

1. Exchange step in the task calls the DECforms form that prompts the user to enter an Employee ID number.
2. DECforms form prompts the user for an Employee ID number, and returns that number to the task.
3. Processing step in the task calls the server procedure that connects to the IBM system.
4. COBOL procedure passes the Employee ID number to a CICS application on the IBM machine. The CICS application uses that number to access the employee's record residing in a database on the IBM system. After the record is found, all pertinent employee information is passed back to the ACMS task on the Compaq system.
5. Exchange step in the task calls the DECforms form to display the requested employee record.
6. DECforms form displays all of the fields in the employee record on the ACMS user's terminal.

For all this work to take place, the sample uses four separate files:

- EMPLOYEE_INFO_READ_TASK task definition, an ACMS file that controls the flow of work at run time
- EMPLOYEE_INFO_PROMPT_FORM form definition, a DECforms file that prompts the user for the Employee ID number
- READ_EMPL_INFO server procedure, a COBOL procedure that accesses the IBM database through a CICS transaction, reads the employee record, and returns that record to the ACMS application
- EMPLOYEE_INFO_FORM form definition, a DECforms file that displays all the fields in the employee record on the ACMS user's terminal

The code for the sample files is contained in the following sections, along with an explanation of what is happening in each file.

## 14.1.1 Task Definition

Example 14-1 shows the ACMS task definition for the sample (EMPLOYEE_INFO_READ_TASK). The task uses exchange steps to get the employee number from the user and to display the employee information to the user. The task uses a processing step to call the COBOL procedure, which handles the I/O interactions among the ACMS application, the IBM CICS application, and the database.

Table 14-1 describes the coding in the EMPLOYEE_INFO_READ_TASK task definition in more detail.

Example 14-1 EMPLOYEE_INFO_READ_TASK Task Definition

       REPLACE TASK EMPLOYEE_INFO_READ_TASK                                [TSK1]
       USE WORKSPACES                                                      [TSK2]
        EMPLOYEE_INFO_WKSP,
        EMPLOYEE_INFO_COMPARE_WKSP,
        QUIT_WORKSPACE,
        CONTROL_WORKSPACE;

       BLOCK WORK WITH FORM I/O                                            [TSK3]

       GET_EMPL_NUMBER:                                                    [TSK4]
        EXCHANGE
        RECEIVE FORM RECORD EMPLOYEE_INFO_RECORD
        IN EMPLOYEE_INFO_PROMPT_LABEL
        RECEIVING EMPLOYEE_INFO_WKSP
        WITH RECEIVE CONTROL QUIT_WORKSPACE;

        CONTROL FIELD IS QUIT_WORKSPACE.QUIT_KEY
           " FQUT"  :  EXIT TASK;
        END CONTROL FIELD;

       RETRIEVE_EMPL_INFO:                                                 [TSK5]
       PROCESSING
         CALL READ_EMPL_INFO IN EMPL_SERVER
         USING EMPLOYEE_INFO_WKSP, EMPLOYEE_INFO_COMPARE_WKSP, CONTROL_WORKSPACE;

       DISPLAY_INFO_TO_USER:                                               [TSK6]
       EXCHANGE
        SEND FORM RECORD EMPLOYEE_INFO_RECORD
           IN EMPLOYEE_INFO_LABEL
        SENDING EMPLOYEE_INFO_WKSP;

       END BLOCK WORK;

       END DEFINITION;

Table 14-1 Description of Code for EMPLOYEE_INFO_READ_TASK Task Definition
Callout | Description
--- | ---
`[TSK1]` | Replaces an old CDD dictionary task definition with the current task definition or creates a new definition if one does not already exist. Section 14.4 discusses the role of the CDD dictionary.
`[TSK2]` | Names one or more workspaces to which the task needs access. Workspaces are buffers used to pass data between steps in a task, between a task and a procedure, between a task and a form, and between two or more tasks.
`[TSK3]` | Groups multiple steps as a logical unit between the BLOCK WORK and END BLOCK WORK clauses (in this example, the block consists of two EXCHANGE steps and one PROCESSING step). FORM I/O is a block phrase that indicates that the EXCHANGE steps use DECforms for I/O with the user.
`[TSK4]` | Calls the DECforms form EMPLOYEE_INFO_PROMPT_FORM within an EXCHANGE step. DECforms uses the EMPLOYEE_INFO_PROMPT_FORM form to prompt the user for an Employee ID number. Once the user supplies that number, control returns to the ACMS task. If the user decides to quit the task when prompted for the Employee ID number, the user can press a predefined quit key. The CONTROL FIELD clause indicates that if the user presses the quit key, ACMS exits the entire task and return control to the ACMS menu.
`[TSK5]` | Calls the COBOL procedure READ_EMPL_INFO within a PROCESSING step. The COBOL procedure performs the database inquiry and returns the employee record to the ACMS application using the EMPLOYEE_INFO_WKSP workspace.
`[TSK6]` | Calls the DECforms form EMPLOYEE_INFO_FORM within an EXCHANGE step. DECforms uses the EMPLOYEE_INFO_FORM to format and display all of the fields in the employee record on the ACMS user's terminal.

## 14.1.2 Prompt Form Definition

Example 14-2 is the DECforms form definition for the sample prompt form (EMPLOYEE_INFO_PROMPT_FORM). In this example, the form prompts the user for the Employee ID number. The Employee ID number is then passed back to the ACMS task, which supplies the Employee ID number to the procedure server.

This code is not hand-generated, but rather is generated by the DECforms Forms Development Environment, an easy-to-use interface for forms generation. Because this coding is computer-generated (programmers do not need to generate this code), there is no detailed explanation of the code following the example.

Example 14-2 EMPLOYEE_INFO_PROMPT_FORM Form Definition

    Form EMPLOYEE_INFO_PROMPT_FORM

        Form Data
            EMPL_NUMBER Character(6)
        End Data

        Form Record EMPLOYEE_INFO_RECORD
        copy
            employee_info_record from dictionary
        end copy
        end record

       /**************************************
        *defines several function responses: *
        **************************************/
        Layout VT_LAYOUT
            Device
                Terminal
                    Type %VT100
            End Device
            Size 24 Lines by 80 Columns

            Function QUIT_KEY
                Is %PF4
            End Function

            Function Response QUIT_KEY
                Remove All
                Return
                    " FQUT"
            End Response

            Disable Response
                Request Exit Response
                    Remove All
                End Response
            End Response

       /**************************************************
        *Describes the display for the first panel in the*
        *employee inquiry example:                       *
        **************************************************/

            Panel EMPLOYEE_PROMPT_PANEL

                Remove

               Literal Text
                    Line 1
                    Column 25
                    Value "EMPLOYEE INQUIRY"
                End Literal

                Literal Text
                    Line 6
                    Column 9
                    Value "Employee Number of Record to View:"
                End Literal

                Literal Text
                    Line 16
                    Column 9
                    Value "Press Ctrl/Z to transmit employee number; PF4 to cancel."
                End Literal

                Field EMPL_NUMBER
                    Line 6
                    Column 47
                    Entry Response
                        Reset EMPL_NUMBER
                    End Response
                End Field

            End Panel

        End Layout
    End Form

## 14.1.3 Read Database COBOL Step Procedure

The COBOL procedure (READ_EMPL_INFO) in Example 14-3, which is a processing step procedure that becomes part of the EMPL_SERVER procedure server, performs the following functions at run time:

- Allocates and deallocates the channel for the conversation between the Compaq and IBM system. ( Section 14.3 shows how sessions are created and deleted between the Compaq and IBM system.)
- Starts an IBM CICS transaction to read the employee record.
- Translates the record from EBCDIC to ASCII and back to EBCDIC.

Note Although COBOL is used in this example, users can create server procedures using any programming language that supports the OpenVMS Calling Standard.

Table 14-2 describes the coding in the READ_EMPL_INFO_COBOL step procedure in more detail.

Note If your step procedures involve write, modify, or delete operations, Compaq suggests you use a timestamp from the IBM system. The timestamp field is given by the IBM transaction to each requester (in this case, the step procedure) as part of the requested record. You can then pass this timestamp back to the IBM system for database locking purposes (do this without converting it from EBCDIC-ASCII then ASCII-EBCDIC). It is the responsibility of the IBM system to check the timestamp field in the file with the new record. If the timestamp fields are different, the record has been modified by a different transaction. Writing step procedures is fully described in Compaq ACMS for OpenVMS Writing Server Procedures.

Example 14-3 READ_EMPL_INFO COBOL Step Procedure

    IDENTIFICATION DIVISION.
    PROGRAM-ID. READ_EMPL_INFO.

    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
    SOURCE-COMPUTER.  VAX-11.
    OBJECT-COMPUTER.  VAX-11.

    DATA DIVISION.

    WORKING-STORAGE SECTION.                                               [SRV1]

    01  resource-id             pic 9(9)    comp.
    01  status-result           pic S9(9)   comp.
    01  i-status                pic S9(9)   comp.
    01  i-ctr                   pic S9(4)   comp.
    01  status-vec              pic X(64) is external.
    01  lu-name                 pic X(5)  is external.
    01  tpn-name                pic X(4).
    01  event-flag              pic 9(8)    comp value 5.
    01  what-received           pic 9(8)    comp.
    01  rts-rec                 pic 9(4)    comp.
    01  record-number           pic X(6).
    01  data-length             pic 9(04)   comp.
    01  data-buffer             pic X(86).
    01  temp-length             pic 9(4).
    01  flag-for-connect        pic X      value SPACE.
    01  nodename-gateway        pic X(6)   is external.
    01  ascii-tpn-name          pic X(4)   value "AIBR".
    01  access-name             pic X(7)   is external.

    01  output-buffer.
        02  o-filler1           pic X(13).
        02  o-name              pic X(20).
        02  o-addrx             pic X(20).
        02  o-phone             pic X(8).
        02  o-datex             pic X(8).
        02  o-amount            pic X(8).
        02  o-comment           pic X(9).

    01  session-status          pic X is external.
        88 session-connected       value 'Y'.
        88 session-not-connected   value 'N'.

    *******************************************************************************
    * SNA LU6.2 APPC - Symbols definition
    *******************************************************************************
    01  SNALU62$_DEALNOR                pic 9(8) comp value 34832986.
    01  SNALU62$_OK                     pic 9(8) comp value 34833145.
    01  SNALU62$K_OTHER                 pic 9(8) comp value 2.
    01  SNALU62$K_MAPPED_CONVERSATION   pic 9(8) comp value 4.
    01  SNALU62$K_WHEN_SESSION_ALLOC    pic 9(8) comp value 5.
    01  SNALU62$K_SL_CONFIRM            pic 9(8) comp value 9.
    01  SNALU62$K_LOCAL                 pic 9(8) comp value 32.
    01  SNALU62$K_DATA_COMPLETE         pic 9(8) comp value 38.
    *******************************************************************************
    * Buffer passed on during conversation to turn off the state conversation
    * between OpenVMS and MVS.
    *******************************************************************************
    01  dummy-record        pic X(2000) value SPACES.
    01  dummy-record_length pic 9(4) comp value 2000.

    LINKAGE SECTION.
    COPY "EMPLOYEE_INFO_WKSP" FROM DICTIONARY REPLACING                    [SRV2]
        ==EMPLOYEE_INFO_WKSP. == BY ==EMPLOYEE_INFO_LINKAGE_WKSP. ==.
    COPY "CONTROL_WORKSPACE" FROM DICTIONARY.

    PROCEDURE DIVISION USING EMPLOYEE_INFO_LINKAGE_WKSP, CONTROL_WORKSPACE.

    MAIN SECTION.
    000-SET-STATUS.
        MOVE SPACES TO ERROR_STATUS_FIELD.

    010-GET-RECORD.

    *************************
    * initialize work fields*
    *************************

            move 0 to data-length, temp-length.

            move spaces to data-buffer, output-buffer.

    *********************************
    * Allocate an LU6.2 conversation.*
    *********************************
            move 0 TO rts-rec.

    *********************************************************
    * Allocate the conversation.                            *
    * Prior we want to convert transaction name into EBCDIC.*
    *********************************************************

        call "LIB$TRA_ASC_EBC" using by descriptor ascii-tpn-name,         [SRV3]
                                                   tpn-name,
                               giving status-result.

        call "SYS$CLREF" using by value event-flag giving i-status.        [SRV4]

        call "SNALU62$ALLOCATE" using                                      [SRV5]
                by reference  resource-id,
                by descriptor status-vec,
                by reference  SNALU62$K_OTHER,
                by descriptor lu-name,
                by value 0,
                by descriptor tpn-name,
                by reference  SNALU62$K_MAPPED_CONVERSATION,
                by reference  SNALU62$K_WHEN_SESSION_ALLOC,
                by reference  SNALU62$K_SL_CONFIRM,
                by value 0,0,0,0,0,
                by reference  event-flag,
                                giving status-result.

        call "SYS$WAITFR" using by value event-flag giving i-status.       [SRV6]
        if status-result IS FAILURE
            go to 100-EXIT-PROGRAM.

    ***********************************
    * Translate the request to EBCDIC.*
    ***********************************

            call "LIB$TRA_ASC_EBC" using by descriptor                     [SRV7]
                                    empl_number of employee_info_linkage_wksp
                                    record-number,
                                    giving status-result.

    *************************************
    * Send the data to CICS transaction.*
    *************************************

            call "SNALU62$SEND_DATA" using                                 [SRV8]
                            by reference resource-id,
                            by descriptor status-vec,
                            by descriptor record-number,
                            by reference data-length,rts-rec,
                                     giving status-result.

            if status-result IS FAILURE
            go to 100-EXIT-PROGRAM.

    ***************************************
    * Receive and wait from the IBM system*
    ***************************************

            call "SNALU62$RECEIVE_AND_WAIT" using                          [SRV9]
                            by reference resource-id,
                            by descriptor status-vec,
                            by value 0,
                            by reference data-length,rts-rec,
                            by descriptor data-buffer,
                            by reference what-received,
                                            giving status-result.

            if status-result is FAILURE
            then
                    if not status-result = SNALU62$_DEALNOR
                    go to 100-EXIT-PROGRAM.

    *********************************************
    * Translate the record from EBCDIC to ASCII.*
    *********************************************

            call "LIB$TRA_EBC_ASC" using by descriptor data-buffer,        [SRV10]
                                                       output-buffer,
                                   giving status-result.

            move o-name to empl_name of employee_info_linkage_wksp.
            move o-addrx to empl_street_address of employee_info_linkage_wksp.
            move o-phone to empl_phone of employee_info_linkage_wksp.
            move o-datex to empl_date of employee_info_linkage_wksp.
            move o-amount to empl_amount of employee_info_linkage_wksp.
            move o-comment to empl_comment of employee_info_linkage_wksp.

    *************************************************************************
    * To clear the conversation do the receive with a dummy record of blanks*
    * Translate the request to EBCDIC.                                      *
    *************************************************************************

            move 0 to dummy-record-length.                                 [SRV11]
            move spaces to dummy-record.

            call "LIB$TRA_ASC_EBC" using by descriptor dummy-record,
                                                       dummy-record,
                                            giving status-result.

            perform 200-clear-receive through 200-clear-receive_x with test after
            until status-result = SNALU62$_DEALNOR
            or status-result is FAILURE.

            if status-result is FAILURE
            then
                    if not status-result = SNALU62$_DEALNOR
                    go to 100-EXIT-PROGRAM.

    ******************************
    * Deallocate the conversation*
    ******************************

        call "SNALU62$DEALLOCATE" using  by reference resource-id,         [SRV12]
                                     by descriptor status-vec,
                                     by reference SNALU62$K_LOCAL,
                              giving status-result.

           if status-result is FAILURE
           go to 100-EXIT-PROGRAM.

    100-EXIT-PROGRAM.
        EXIT PROGRAM.

    200-clear-receive.

            call "SNALU62$RECEIVE_AND_WAIT" using                          [SRV13]
                            by reference resource-id,
                            by descriptor status-vec,
                            by value 0,
                            by reference dummy-record_length,rts-rec,
                            by descriptor dummy-record,
                            by reference what-received,
                            giving status-result.

    200-clear_receive_x.

Table 14-2 Description of Code for READ_EMPL_INFO COBOL Step Procedure
Callout | Description
--- | ---
`[SRV1]` | Defines the variables and data types that this COBOL procedure uses.
`[SRV2]` | Copies the EMPLOYEE_INFO_WKSP employee record definition from the CDD dictionary, and refers to the record definition as EMPLOYEE_INFO_LINKAGE_WKSP in this COBOL procedure.
`[SRV3]` | Calls the LIB$TRA_ASC_EBC OpenVMS run-time library system routine, which translates the transaction name from the ASCII format used on Compaq systems to the EBCDIC format used on IBM systems.
`[SRV4]` | Calls the SYS$CLREF OpenVMS system service, which clears the field for the event flag.
`[SRV5]` | Calls the SNALU62$ALLOCATE APPC/LU6.2 procedure, which initiates a conversation (a short-term connection) between this COBOL procedure and the remote IBM CICS application.
`[SRV6]` | Calls the SYS$WAITFR OpenVMS system service, which waits for the event flag to be set by the SNALU62$ALLOCATE APPC/LU6.2 call. If the result of the attempt to initiate a conversation is a failure, the COBOL procedure is exited and control returns to the task.
`[SRV7]` | Calls the LIB$TRA_ASC_EBC OpenVMS run-time library system routine, which translates the Employee ID number from the ASCII format used on Compaq systems to the EBCDIC format used on IBM systems.
`[SRV8]` | Calls the SNALU62$SEND_DATA APPC/LU6.2 procedure, which sends the Employee ID number (in EBCDIC format) to the CICS application.
`[SRV9]` | Calls the SNALU62$RECEIVE_AND_WAIT APPC/LU6.2 procedure, which waits for the CICS application to return the full employee record to this COBOL procedure.
`[SRV10]` | Calls the LIB$TRA_EBC_ASC OpenVMS run-time library system routine, which translates the employee record from EBCDIC to ASCII format so that the data can be used on the Compaq system. The data is then copied to the EMPLOYEE_INFO_LINKAGE_WKSP workspace, so that it can be accessed by the ACMS task.
`[SRV11]` | Initializes a dummy record and translates that dummy record from ASCII to EBCDIC format. This cleanup work is done to clear the conversation with the IBM machine so that the next conversation can occur.
`[SRV12]` | Calls the SNALU62$DEALLOCATE APPC/LU6.2 procedure, which deallocates the conversation (connection) between this COBOL procedure and the CICS application.
`[SRV13]` | Calls the SNALU62$RECEIVE_AND_WAIT procedure, which waits for the dummy record to be returned to the COBOL procedure from the CICS application to clear the connection. Note that this call is actually made from `[SRV11]`.

Previous | Next | Contents | Index