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:

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:

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