ステップ3. サーバー・ファンクションiiiFN05を作成する
このステップでは、ユーザー・エージェントからデータを受け取って処理し、ユーザー・エージェントにデータを返すLANSA RDMLXサーバー・ファンクションを作成します。ファンクションは、SET233Sファンクションとかなり似ています。
1. Visual LANSA開発環境を使用する場合、チュートリアルに指定された区画(通常はDEM)にサイン・オンします。
2. iiiPRO03 User Agent Server Test Processという新しいLANSAプロセスを作成します。iiiは一意の3文字です(プロセスがすでにある場合は、iiiに対して別の文字セットを選択します)。
3. プロセスiiiPRO03に属するiiiFN05 Receive and Process Salary Amendmentsという新しいRDMLXファンクションを作成します。iiiは一意の3文字です。RDMLXチェックボックスはチェックしてください。ファンクションがアプリケーションのテンプレートから生成されるように指定します。
4. テンプレートのリストで、JSMXSKELというテンプレートを選択します。
5. 以下の表に示すテンプレートの質問に回答します。
質問 |
回答 |
説明 |
---|---|---|
JSMサービスをロードしますか? |
HTTPSERVICE |
6. ファンクションiiiFN05のRDMLXコードを編集します。
このファンクションには2つの作業リストが必要です。
· 作業リストS_233RCVは、ユーザー・エージェントから送信されたCSVファイルのデータを受け取る場合に使用されます。このファンクションでは、CSVファイルに他の情報がある場合でも、社員番号と給与の使用だけに専念します。
· 作業リストS_233SNDは、このサーバー・ファンクションからユーザー・エージェントに応答を返す場合に使用されます。受信リストの更新は許可されていないため、このリストは受信リストとは別のリストにしてください。この場合、ユーザー・エージェントに返されるデータは、社員番号、社員の一部詳細、新しい給与、更新の成功や失敗を示すメッセージを含むテキスト・フィールドになります。
· また、エラーを処理するフィールドS_233ERROも定義する必要があります。
RDMLXコードは以下のように表示されます。
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. SERVICE_LOADコマンドを修正します。KEYWRDサブルーチンを使用して、SERVICE_LOADコマンドに以下のキーワードを追加します。
キーワード |
値 |
SERVICE_CONTENT |
'*HTTP' |
TRACE |
'*YES' |
SERVICE_COMMAND(*HTTP)は、HTTPポスト内容を受け取る場合に必要です。
TRACE(*YES)は、テスト目的の場合に役立ちます。実稼働システムへの配布前にトレースを削除する必要があります。
完了したコードは以下のようになります。
* 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. RDMLXソースの中央付近にあるコメント「ここに処理ロジックを記述してください」を探します。
BBJSMXCMDテンプレートを使用して、社員番号とその新しい給与のリストをCSVファイルから受け取るRDMLXを作成します。サービス・リストの名前の入力が求められた場合は、S_233RCVと入力します。このテーブルを使用して、テンプレートの質問に回答します。
コマンド |
キーワード |
値 |
作業リスト |
---|---|---|---|
RECEIVE |
HANDLER |
ISVL |
S_233RCV |
SVMODE |
'*USE' |
BBJSMXCMDテンプレートの使用の詳細については、「INT003 - FTPサービスの使用」の「ステップ1. 基本のJSMファンクションを作成する」を参照してください。
· ISVLは、インバウンド区切り変数リストに使用されます。
· SVMODEが*USEの場合、列見出しをLANSAフィールド名として使用するようにサービスに伝えられます。
RDMLXコードは以下のように表示されます。
* 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. 以下のファンクションを行うRDMLコードを作成します。
a. 受信したリストS_233RCVのすべてのエントリーを選択(SELECT)します。
b. EMPNOキーでPSLMSTからGIVENAMEとSURNAMEを取得(FETCH)します。
c. I/Oステータスを確認します。
OK以外の場合、社員が見つからなかったことを示すエラー・フィールドS_233ERROを変更(CHANGE)します。
それ以外の場合は、PSLMSTでSALARYを更新(UPDATE)します。
d. UPDATEのI/Oステータスを確認し、エラー・フィールドS_233ERROを適宜変更(CHANGE)します。
e. LANSAユーザー・エージェントに返される作業リストS_233SNDにエントリーを追加します。
f. ENDSELECT
コードは以下のように表示されます。
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. 上記のコードの下に位置を合わせ、BBJSMXCMDテンプレートを使用して、ユーザー・エージェントに応答リストを返すRDMLXを作成します。このリストには、社員の詳細と、成功/失敗を示すメッセージが含まれています。サービス・リストの名前の入力が求められた場合は、S_233SNDと入力します。このテーブルを使用して、テンプレートの質問に回答します。
コマンド |
キーワード |
値 |
作業リスト |
---|---|---|---|
SEND |
HANDLER |
ISVL |
S_233SND |
· ISVLは、インバウンド区切り変数リストに使用されます。
コードは以下のように表示されます。
#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. SERVICE_UNLOADコマンドを削除します。JSMX_CLOSEコマンドはそのままにしておいてください。
完了したコードは以下のように表示されます。
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. ファンクションをコンパイルします。
13. IBM i サーバーでJSMサーバーを使用している場合、プロセスとファンクションをIBM i に登録してコンパイルします。