メニューボタン
IBMi海外記事2017.11.09

IBM iで.Net、XMLSERVICEプログラムおよびサブプロシージャー呼び出しを使うには

Richard Schoen 著

企業には、かけがえのない貴重なビジネス ロジックが組み込まれている、長年使用されてきたIBM iレガシー アプリケーションがあります。そうしたコードは、書き直しすることなく再利用することで、既存のIBM iのビジネス ロジックが、デスクトップ アプリケーション、Webアプリケーション、Webサービス、およびモバイル デバイス アプリケーションといった、しばしばJSONまたはXMLベースのデータを予期しているアプリケーションからアクセスおよび利用できるようにする必要があります。既存のビジネス ロジックを書き直すのではなく、コードのインターフェースだけ調整して現状のままで呼び出すことができるようにするということです。

この記事では、XMLSERVICEリモート プログラム呼び出しおよびリモート サブプロシージャー呼び出しを中心にお話しします。それらを使用して、.Netアプリから既存のRPG、COBOL、およびCLアプリケーションをベースにした既存のロジックを呼び出すことができます。これにより、現在も使用されている既存のビジネス アプリケーション ロジックをモダナイズしながら活用し続けることが可能になります。

この記事では、以前の記事と同じ前提条件が必要とされます。まだXMLSERVICEアプリケーション コードのインストールとセットアップが完了しておらず、Apache Webサーバー インスタンスが作成されていない場合、まず こちらの導入記事を確認してください。.Netアプリケーション コードが動作するには、XMLSERVICEが稼働している必要があるためです。また、テスト アプリケーションを少なくとも1回は開いて構成し、実行していることを前提としています。

テストCLプログラム呼び出しを実行する

Visual Studioを起動し、XmlServiceApiソリューション ファイルC:\XmlServiceiApi\XmlServiceiApi.slnを読み込んで開きます。XmlServiceApiTesterプロジェクトを見つけて、[Solution Explorer]ウィンドウでFormMain.vbをダブルクリックしてメイン フォームを開きます。

技術情報code01

正しく構成したら、playボタンをクリックするかF5を押してAPIテスター アプリケーションを実行させると、アプリケーション ウィンドウを表示させることができるはずです。APIでリモート プログラム呼び出し機能をテストするには、Run ProgramボタンをクリックしてIBM iライブラリーXMLDOTNETIに含まれるサンプルCLプログラムTESTCL1を実行します(そのライブラリーをロードしていることが前提です)。このプログラム呼び出しはすぐに完了するはずであり、戻り値パラメーターに、応答値 「Thank you for your business」と、2つ目の数値「1000100.22」 が表示されるはずです。

Run Program機能は、CLまたはRPGプログラムからのパラメーター付きの呼び出しと同じように動作するため、.Netアプリは、実行することが許可されているIBM i上の任意のアプリケーションを呼び出すことができます。このプログラム呼び出しから1つ目のパラメーターは空のフィールドとしてCLプログラムへ送られ、テキスト応答メッセージ値が返されました。2つ目の数値では、初期値は100.00で渡され、1000000.22ずつ増加され、操作されて15.2パック形式の数値が返されたことが示されています。この記事では、CLまたはRPGコードの分析は行いませんが、XMLDOTNETIライブラリーを覗いて、プログラムTESTCL1のコードがどれほど簡単か見てみます。

RPGサービス プログラム プロシージャーを実行する

Run Procedureボタンをクリックすると、sample1という名前のサンプルのRPGサブプロシージャーを呼び出すことになります。このサブプロシージャーは、ライブラリーXMLDOTNETI内のサービス プログラムXMLSVC001に含まれています。sample1テスト サブプロシージャーは、受け取ったパラメーターを操作して、元の値に「return value」という単語を連結した新しい値を返します。これは、XMLSERVICEを介してRPGベースのサービス プログラム内に収められているサブプロシージャーを呼び出す際に必要となる一般的なつなぎ方を説明する簡単な方法です。

既存のプログラムおよびサービス プログラム コードを呼び出すことができるということであれば、既存のRPGまたはCOBOLアプリケーションとともに使用できる新たなビジネス ロジックを作成することが可能になりますし、また、.Netおよび他の言語を使用して記述されたリモート アプリケーションから呼び出して同じ結果を返すこともできるようになります。再利用可能なすべてのIBM iビジネス ロジックが、そのまま安全にIBM iシステム上の1つの場所でホスティングされることになります。

CLプログラム呼び出しのコードをレビューする

コードについて、そしてリモートCLプログラムおよびサブプロシージャーを実行したときにどのようなことが起こるかについての概要をざっと見てみましょう。まず、接続パラメーターをセットアップする必要があります。IBM iへの呼び出しをセットアップするには、SetBaseURL関数を使用して、テスト プロジェクト設定から基本URLをXMLSERVICEオブジェクトに設定します。次に、SetUserInfo関数は、設定から目的のIBM iユーザーとパスワードを設定します。実際のアプリケーションでは、ユーザーIDとパスワードを入力するか、IBM iアプリのサービス アカウントを保存するようユーザーに要求することになります。

次に、SetIpcInfo関数は、この接続固有のIPC会話を設定して、ジョブ パーシスタンスが可能な関連IBM iジョブに接続します。次に、SetHttpTimeout関数を使用して、タイムアウトするまでに何秒間HTTP接続しようとするか判断します。トランザクションのタイムアウトは通常30秒です。しかし、希望のトランザクション長に応じて、高い値または低い値を設定できます。アプリケーションがロックしたとユーザーが思わないような長さにするべきです。 すべての接続セットアップ作業が終了したら、TESTCL1プログラムへ渡される2つのパラメーター用のパラメーター リストの配列を作成し、ExecuteProgram関数を使用してライブラリーXMLDOTNETIからプログラムを呼び出します。プログラム呼び出しが正常に終了した場合、関数は「true」を返し、何かが失敗した場合は、「false」を返します。

リモート アプリケーションからCLまたはRPGプログラムおよびサブプロシージャーを呼び出す場合、RPG、CL、またはCOBOLアプリ コード内のどのエラーもIBM iコードが処理する必要がある点を覚えておくことが大切です。コード エラーを処理しないと、IBM iコードは、QSYSOPRメッセージ キューにCPF例外エラー メッセージを投げる場合があります。これは、ユーザーからは、実際はシステム オペレーターからのエラー応答を待っている状態だとしても、.Netアプリケーションがロックしているように見えてしまいます。HTTPサーバーは最終的にタイムアウトしますが、XMLSERVICEによって呼び出されたアプリが、必要に応じて強制停止するのはあまり良いものではないため、IBM iコードでコツコツとコーディングし、エラーはあるという前提で考えてください。リモート コード呼び出しエラーを厳密に処理するのは.Netに限ったことではありません。PHP、Java、Ruby、またはRPGアプリケーションを使用してリモートでコマンドを呼び出す場合、同じ問題が発生することがあります。

技術情報code02

Run Programコマンドボタンのクリック イベントを処理するVBコードをご覧ください。XMLServiceiデータ アクセス オブジェクトを使用して、いかに簡単にパラメーター付きでプログラムを呼び出すことができるかわかります。FormMainをダブルクリックしてデザイナー ウィンドウを開くか、またはFormMain.vbを右クリックして[View Code]を選択し、コード ウィンドウを開きます。FormMain.vbを開いた後のコードを見ると、コード呼び出しに接頭部XMLServiceiApiを付けるといううんざりする作業をする必要がないよう、XMLServiceiApi名前空間をインポート(Imports XMLServiceiApi)していることがわかります。これはデスクトップ アプリケーションであるため、_xmlServiceという変数を作成(Dim _xmlService As New XmlServicei)します。この変数はプログラム起動時に、設定済みの接続情報で初期化されるため、Windowsアプリケーションがアクティブな状態で、同じ接続を再利用することができます。Webアプリケーションの場合、XMLSERVICE接続はステートレスのため、この情報はおそらくWebセッションに保存されているか、ページ呼び出しごとにインスタンス化されているでしょう。

Run Programコードにアクセスするには、Run ProgramコマンドボタンをダブルクリックしてButtonProgram_Clickサブルーチンを開きます。コード呼び出しがすべてTry/Catchルーチンでエラー処理されるようにしていることがわかると思います。これは、CLおよびRPGにおけるMONMSGまたはMONITOR/ENDMONに似ています。また、アプリ構成から接続およびログインの情報をセットアップするのに、SetBaseURL、SetUserInfo、SetIpcInfo、およびSetHttpTimeoutがすべて呼び出されているのがわかると思います。通常、これらの設定はユーザーに入力してもらうようにします。次に、TESTCL1 CLプログラムを実行するExecuteProgram関数への単一の呼び出しが確認できます。CLプログラム呼び出しが完了すると、GetDataTableProgramResponse関数が呼び出され、パラメーター応答をグリッド内に表示できる.Net DataTableフォーマットで呼び出します。次に、必要であれば、GetLastXmlResponseを呼び出して、XML応答ストリング全体を、XMLSERVICEから表示または処理します。XmlServiceiApiを使用する場合、.Netアプリケーションからプログラムを呼び出すのはこれほどに簡単なのです。

もっと突っ込んでみるのならば、XmlServicei.vbソースを開いて、ExecuteProgramコードを見ることもできます。この関数は、HTTP経由でXMLSERVICE xmlcgiプログラムに通知するよう、XMLデータ ストリームを構成することがわかります。次いで、返されたXML応答を処理します。.Net通信プラミングコードはほとんど要求されません。なぜならXMLSERVICEは高負荷なワークのほとんどをIBM i側で行い、セキュアな呼び出しをするためにHTTPまたはHTTPS経由で呼び出すだけだからです。

技術情報code03

RPGサブプロシージャー呼び出しのコードをレビューする

RPGサブプロシージャーを実行するコードをざっと見てみましょう。接続セットアップは、プログラム呼び出しのサンプルと同じです。

セットアップ作業が終了したら、サブプロシージャー呼び出しに渡される入力および戻り値パラメーター用のパラメーター リスト配列を作成します。これは機能的にプログラム呼び出しのサンプルとよく似ています。パラメーター リストを作成したら、ExecuteProgramProcedure関数を使用して、ライブラリーXMLDOTNETI内のサービス プログラムXMLSVC001の中のsample1サブプロシージャーを呼び出します。呼び出しが正常に終了した場合、関数は「true」を返します。そうでない場合は「false」を返し、何かが失敗したことが示されます。

技術情報code04

Run Programコードにアクセスするには、Run ProcedureコマンドボタンをダブルクリックしてButtonProcedure_Clickサブルーチンを開きます。接続およびパラメーター リストのセットアップ コードが呼び出され、次いで、sample1サブプロシージャーを実行するExecuteProgramProcedure関数への単一の呼び出しが確認できます。呼び出しが完了すると、GetDataTableProgramResponse関数が呼び出され、パラメーター応答をグリッド内に表示できる.Net DataTableフォーマットで呼び出します。次に、必要であれば、GetLastXmlResponseを呼び出して、XML応答ストリング全体を、XMLSERVICEから表示または処理します。CLまたはRPGはプログラムの呼び出しと同様に、.NetアプリケーションからRPGサブプロシージャーを呼び出すのはこれほどに簡単なのです。

技術情報code05

コードを入手する

以上を持ちまして、.NetでXMLSERVICEを使用する方法についての私のシリーズ記事は完了となります。先日、私はこのプロジェクトを私の GitHubリポジトリ へアップロードしました。近頃では、そうすることが、オープンソース プロジェクトのために行うべきことのように思われるからです。アップロードに際して、プロジェクトのソースを新しい.Net Standardフォーマットへと移植しました。そうすることにより、DLLアセンブリが、Windows向けの標準.Netプロジェクトだけでなく、Windows、Linux、およびMacOS上で動作できる.Net Core 2.0マルチプラットフォーム プロジェクトでも使用することが可能になります。さらに、IbmiXmlserviceStdというnugetパッケージも作成しました。これを使うと、最新のコンパイルされたDLLを任意の.Netプロジェクトへ数秒で追加できます。

WindowsおよびLinux用の.Net Coreの適切なドライバーを、IBMがリリースしてくれるという期待は持てそうにないため、XMLSERVICEこそが、すべての.Net CoreアプリにとってのIBM iとの通信のための解決策ということになるかもしれません。他にも新たな.NetおよびIBM i関連プロジェクトがアップされていますので、GitHubリポジトリをチェックされることをお勧めします。

あわせて読みたい記事

PAGE TOP