Step 3 Create a Server Function iiiFN05

LANSA Integrator

Step 3. Create a Server Function iiiFN05

INT004 - Using the LANSA User Agent

In this step, you will write the LANSA RDMLX server function that will receive the data from the User Agent, process it, and return data to the User Agent. Your function will be very similar to the SET233S function.

1.  Using the Visual LANSA development environment, sign on to the partition nominated for the tutorials (usually DEM).

2.  Create a new LANSA process named iiiPRO03 User Agent Server Test Process, where iii is your unique 3 characters. (If the process already exists, select a different set of characters for iii.)

3.  Create a new RDMLX enabled function named iiiFN05 Receive and Process Salary Amendments, belonging to process iiiPRO03, where iii is your unique 3 characters. Note that the RDMLX checkbox must be checked.

4.  From the list of templates, select the template called JSMXSKEL.

5.  Answer the template questions as shown in the table below.

Question

Answer

Comments

Do you wish to load a JSM Service?

HTTPSERVICE

 

 

 

6.  Edit the RDMLX code of function iiiFN05.

     This function will require two working lists:

  • Working list S_233RCV is used to receive the data from the CSV file sent by the User Agent. In this function, you are only interested in using the employee number and the salary even though the CSV file contains more information.
  • Working list S_233SND is used to return the response from this server function to the User Agent. This list must be a different list from the receive list, because no updating of the receive list is allowed. In this case, the data returned to the User agent will be the employee number, some employee details, the new salary and a text field with a message indicating success or failure of the update.
  • You will also need to define a field S_233ERRO for handling errors.

     The RDMLX code might appear as follows:

DEF_LIST  NAME(#S_233RCV) FIELDS(#EMPNO #SALARY) TYPE(*WORKING)
DEFINE    FIELD(#S_233ERRO) TYPE(*CHAR) LENGTH(132) INPUT_ATR(LC)
DEF_LIST  NAME(#S_233SND) FIELDS(#EMPNO #GIVENAME #SURNAME #SALARY #S_233ERRO)TYPE(*WORKING) 
 

7.  Modify the SERVICE_LOAD command.  Use the KEYWRD subroutine to add the following keywords to the SERVICE_LOAD command

Keyword

Value

SERVICE_CONTENT

'*HTTP'

TRACE

'*YES'

 

     The SERVICE_COMMAND(*HTTP) is required to receive HTTP posted content .

     The TRACE(*YES) may be useful for testing purposes. You should remove trace before deploying to a production system.

     Your completed code should look like the following. Changes are shown in red.

* BUILD THE SERVICE LOAD COMMAND
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD 'SERVICE' 'HTTPSERVICE')
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD 'SERVICE_CONTENT' '*HTTP')
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD 'TRACE' '*YES')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK_STS) WITH_PARMS(#JSMXHDLE1)
 

8.  Locate the comment around the middle of the RDMLX source that says YOUR OWN LOGIC HERE.

     On the Design ribbon, click on the Templates button and use the BBJSMXCMD template to write the RDMLX to RECEIVE the list of employee numbers and their new salaries from the CSV file. When prompted to type in the name of the Service List, type S_233RCV. Use this table to answer the template questions.

Command

Keyword

Value

Working List

RECEIVE

HANDLER

ISVL

S_233RCV

 

 

SVMODE

'*USE'

 

 

Enclose *USE in single quotes, as shown.

     For more detailed information on using the BBJSMXCMD template, refer to INT003 – Using the FTP Service, Step 1. Build the basic JSM Functions.

  • ISVL is used for Inbound Separated Variable List.
  • SVMODE of *USE tells the service that you want to use the column headings as the LANSA field names.

     The RDMLX code might appear as follows:

* BUILD THE JSM COMMAND
#JSMXCMD := RECEIVE
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD HANDLER ISVL)
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD SVMODE '*USE')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMSTS #JSMMSG #S_233RCV)
EXECUTE SUBROUTINE(CHECK_STS) WITH_PARMS(#JSMXCMD) 
 

9.  Continue the YOUR OWN LOGIC SECTION by writing the RDML code to achieve the following functions:

a.  SELECTLIST all the entries from the received list S_233RCV.

b.  FETCH GIVENAME and SURNAME from PSLMST with key EMPNO.

c.  Check the I/O status.

   If not okay, CHANGE the error field S_233ERRO to say that the employee was not found.

   Else UPDATE SALARY in PSLMST.

d.  Check the I/O status of the UPDATE, and CHANGE the error field S_233ERRO accordingly.

e.  Add an entry to the working list S_233SND to be returned the LANSA User Agent.

f.  ENDSELECT

     The code might appear as follows:

SELECTLIST NAMED(#S_233RCV)
CHANGE FIELD(#GIVENAME #SURNAME) TO(*NULL)

FETCH FIELDS(#SURNAME #GIVENAME) FROM_FILE(PSLMST) WITH_KEY(#EMPNO)
IF_STATUS IS_NOT(*OKAY)
#S_233ERRO := 'Unsuccesful: Employee not found'
ELSE 

UPDATE FIELDS(#SALARY) IN_FILE(PSLMST) IO_ERROR(*NEXT) VAL_ERROR(*NEXT)
IF_STATUS IS_NOT(*OKAY)
#S_233ERRO := 'Unsuccesful: Employee found but update failed'

ELSE
#S_233ERRO := 'Succesful: Salary of employee ' + #EMPNO + 'succesfully updated'
ENDIF
ENDIF
ADD_ENTRY TO_LIST(#S_233SND)
ENDSELECT
 

10.Position below the above code, use the BBJSMXCMD template to write the RDMLX to SEND the response list back to the User Agent. The list will contain employee details and a success/failure message.  When prompted to type in the name of the Service List, enter S_233SND. Use this table to answer the template questions.

Command

Keyword

Value

Working List

SEND

HANDLER

ISVL

S_233SND

 

 

  • ISVL is used for Inbound Separated Variable List.

     The code might appear as follows:

#JSMXCMD := SEND
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(HANDLER ISVL)
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMSTS #JSMMSG #S_233SND)
EXECUTE SUBROUTINE(CHECK_STS)
 

11.Delete the SERVICE_UNLOAD command.

Make sure that you leave the JSMX_CLOSE command in place.

Your finished code might appear as follows:

FUNCTION OPTIONS(*DIRECT)
DEF_LIST NAME(#S_233RCV) FIELDS(#EMPNO #SALARY) TYPE(*WORKING)
DEFINE FIELD(#S_233ERRO) TYPE(*CHAR) LENGTH(132) INPUT_ATR(LC)
DEF_LIST NAME(#S_233SND) FIELDS(#EMPNO #GIVENAME #SURNAME #SALARY #S_233ERRO) TYPE(*WORKING)
*
*  OPEN JSM AND VERIFY STATUS
USE BUILTIN(JSMX_OPEN) TO_GET(#JSMSTS #JSMMSG #JSMXHDLE1)
EXECUTE SUBROUTINE(CHECK_STS) WITH_PARMS(#JSMXHDLE1)
*
* BUILD THE SERVICE LOAD COMMAND
#JSMXCMD := 'SERVICE_LOAD'
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD 'SERVICE' 'HTTPSERVICE')
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD 'SERVICE_CONTENT' '*HTTP')
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD 'TRACE' '*YES')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK_STS) WITH_PARMS(#JSMXHDLE1)
*
*     YOUR OWN LOGIC HERE
* BUILD THE JSM COMMAND
#JSMXCMD := RECEIVE
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD HANDLER ISVL)
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD SVMODE '*USE')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMSTS #JSMMSG #S_233RCV)
EXECUTE SUBROUTINE(CHECK_STS) WITH_PARMS(#JSMXCMD)
*
SELECTLIST NAMED(#S_233RCV)
CHANGE FIELD(#GIVENAME #SURNAME) TO(*NULL)

FETCH FIELDS(#SURNAME #GIVENAME) FROM_FILE(PSLMST) WITH_KEY(#EMPNO)
IF_STATUS IS_NOT(*OKAY)
#S_233ERRO := 'Unsuccesful: Employee not found'
ELSE 

UPDATE FIELDS(#SALARY) IN_FILE(PSLMST) IO_ERROR(*NEXT) VAL_ERROR(*NEXT)
IF_STATUS IS_NOT(*OKAY)
#S_233ERRO := 'Unsuccesful: Employee found but update failed'

ELSE
#S_233ERRO := 'Succesful: Salary of employee ' + #EMPNO + 'succesfully updated'
ENDIF
ENDIF
ADD_ENTRY TO_LIST(#S_233SND)
ENDSELECT
*
* BUILD THE JSM COMMAND
#JSMXCMD := SEND
EXECUTE SUBROUTINE(KEYWRD) WITH_PARMS(#JSMXCMD HANDLER ISVL)
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMSTS #JSMMSG #S_233SND)
EXECUTE SUBROUTINE(CHECK_STS) WITH_PARMS(#JSMXCMD)
*
* CLOSE JSM AND VERIFY STATUS
USE BUILTIN(JSMX_CLOSE) WITH_ARGS(#JSMXHDLE1) TO_GET(#JSMSTS #JSMMSG)
EXECUTE SUBROUTINE(CHECK_STS) WITH_PARMS(#JSMXHDLE1)
RETURN
*
* Subroutine to build JSM commands. existing JSM command
*
SUBROUTINE NAME(KEYWRD) PARMS((#W_CMDX *BOTH) (#W_KEYWRD *RECEIVED) (#W_KEYVAL *RECEIVED))
DEFINE FIELD(#W_CMDX) REFFLD(#JSMXCMD)
DEFINE FIELD(#W_KEYWRD) REFFLD(#STD_TEXT)
DEFINE FIELD(#W_KEYVAL) REFFLD(#STD_TEXTL)
#W_CMDX += ' ' + #W_KEYWRD + '(' + #W_KEYVAL + ')'
ENDROUTINE
*
*  Check the status of the JSM command issued
*
SUBROUTINE NAME(CHECK_STS) PARMS(#W_HDLE)
DEFINE FIELD(#MSGDTA) TYPE(*CHAR) LENGTH(132)
DEFINE FIELD(#W_HDLE) TYPE(*CHAR) LENGTH(4)
*
IF COND('#JSMSTS *NE OK')
*
#MSGDTA := 'Error Status Code: ' + #JSMSTS
MESSAGE MSGID(DCM9899) MSGF(DC@M01) MSGDTA(#MSGDTA)
#MSGDTA := 'Error Message: ' + #JSMMSG
MESSAGE MSGID(DCM9899) MSGF(DC@M01) MSGDTA(#MSGDTA)
ENDIF
*
ENDROUTINE
 

12.Compile the function.

13.If you are using a JSM Server on an IBM i server, check in and compile your process and function on the IBM i.