こんにちは。CData Software Japan リードエンジニアの杉本です。
以前このBlog ではSAP S/4 HANA にRFC プロトコルで接続する方法や、OData での接続方法について解説してきました。
https://www.cdata.com/jp/blog/saperpfunctionmodulerfc
https://www.cdata.com/jp/blog/sapnetweavergatewayes5
SAP はその特性上、RFCやOData サービスがあらかじめすべての機能に対して存在するわけではなく、都度インターフェースをカスタマイズ・開発を行って連携を実装していくのが一般的なようです。
Salesforce やDynamics 365 などはあらかじめ汎用的なAPI として実装されているので、このあたりはカルチャーの違いとして興味深いですね。
というわけで、CData 製品としてはややスコープ外なお話ではありますが、今回はSAP のOData サービスの実装を1から試してみたいと思います。最終的には実装したOData サービスに対して、CData Driver からも接続してみます。
ちなみに環境はSAP S/4 HANA Private Cloud Edition を利用しましたが、Public Cloud Edition でも同様に実行できるのかなと思います。
https://www.cdata.com/jp/blog/saps4hanatrial
今回作成するOData サービス
今回作成するOData サービスは以下のようなBNKA(銀行マスタ)のデータを一覧取得(GetEntitySet)するOData サービスとして実装します。
OData の仕様上、CRUD操作をサポートするインターフェースとして、Create・Delete・GetEntity(単一レコードの取得)・GetEntitySet(複数レコードの取得)・Update がありますが、とりあえず今回はあまり範囲を広くせず、GetEntitySet を必要最小限で実装し、OData サービスとして公開する、というところまでやってみます。
今後気が向いたら、他の実装も試して見るかもしれませんが、まずはODataというのがどういう風に実装できるものなのか? の理解に重点を当てています。
SAP 環境へログイン
それでは作業開始です。まず構成したSAP の環境へSAP Logon でアクセスします。
User アカウントはあらかじめ用意されているBPINST を利用しました。ここは皆様のお持ちの環境に合わせて調整してください。
SAP Gateway Service Builder でプロジェクトを作成
ログイン後、トランザクションコード「SEGW」を入力して、SAP Gateway Service Builder の画面を呼び出します。
この画面でOData サービスの実装を進めていきます。
まず最初に今回のOData サービスの実装を行うプロジェクトを作成しましょう。
この中で一番わかりにくいのは「Project Type」ですかね。アノテーションというのはODataのメタデータ仕様では表現できない、SAP独自のメタデータ付与機能のことを指すようです。
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abensap_annotation_glosry.htm
今回は特に独自のアノテーションなどは利用する想定が無いため、デフォルトの「Service with SAP Annotations」を選択して、作成を進めます。
https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_751_IP/68bf513362174d54b58cddec28794093/6c4f22518bc72214e10000000a44176d.html
データモデルの追加
プロジェクトを作成したら、まずOData サービスの中で利用するデータモデルを作成しましょう。これは最終的にデータのやり取りを行う上での項目や形の定義として利用します。
今回は既存のBNKA テーブルを元に実装を進めるため、Import で選択できる「DDIC Structure」から作成します。
任意のName を指定し、ABAP Structure としてBNKA を選択します。
以下のようにBNKA の項目一覧が表示されるので、とりあえず今回は全部選択します。
OData サービスの実装ではKey が必須みたいなので、必要な項目にKey を指定します。ちなみにこれはOData インターフェース上のKey の定義であり、実際に格納されるデータの一意性を保証するものではありません。
これで以下のようにデータモデルが取り込めました。
さらに、BNKA のデータモデルを操作するためのCreate・Delete・GetEntity(Read)・GetEntitySet(Query)・Updateの実装の型まで生成してくれます。
ただ、これはあくまでインターフェースだけが出来上がった状態であり、実装はまだ何も存在しません。
ランタイムオブジェクトの生成
続いて、出来上がったインターフェースの実装に関連するABAPのクラス、ランタイムオブジェクトを生成しましょう。一度プロジェクトを保存し、ランタイムオブジェクトの生成ボタンをクリックします。
以下のように生成するクラスの名前を指定する画面が表示されます。自動的に候補が入力された状態で表示されるので、ここではデフォルトのままで作業を進めます。
生成が完了すると、Runtime Artifacts が以下のように追加されます。ここにそれぞれのインターフェースの実装クラスやOData サービスとして登録するためのクラスが定義されます。
この状態でService Implementation を見てみると、それぞれのインターフェースにImplementation Class NameとMethod Nameが紐づけされいるのがわかるかなと思います。
今後ここのクラス・メソッドにABAPのコードを書いて、インターフェースでやり取りを行うデータ処理の実装を進めるイメージになります。
OData サービスに登録する
それではまだ何もインターフェース内部の実装は進んでいない状態ですが、一旦OData サービスとしてリクエストできるようにサービス登録をしてみましょう。
OData のサービス登録や管理は「/IWFND/MAINT_SERVICE」を使って行います。
「/IWFND/MAINT_SERVICE」に移動後、Add Service をクリックします。
任意のSystem Alas を選択し、「Get Services」をクリックしましょう。
すると先程SAP Gateway Service Builder のRuntime Artifacts として登録されたサービスが表示されます。
これを選択し「Add Selected Services」で登録しましょう。
サービスの登録情報はデフォルトのままで進めます。
これで以下のようにサービスが登録され、OData API として外部からコールすることができるようにうなります。画面左下にある「SAP Gateway Client」を使って、確認してみましょう。
以下のようにPostman のようなAPI Client が表示されるので、Execute ボタンをクリックします。
すると生成したサービスからBNKA のEntitySet がコールできることが確認できるメタデータを確認できます。
もちろん、このまま「/CDATA_SAMPLE_SRV/BNKASet」をコールすることもできますが、まだGetEntitySet の内部実装が完了していないため、実際のデータを取得することはできません。
そのため、次にGetEntitySet 内部の実装を進めていきましょう。
GetEntitySet の内部実装を行う
それでは一旦SAP Gateway Service Builder に戻って、内部実装を行います。
先ほど登録したBNKA のService Implementation にある「GetEntitySet(Query)」を右クリックし「Go to ABAP Workbench」をクリックします。
この画面からインターフェースの内部実装を進めていきます。Runtime Artifacts で説明したように、各OData サービスのImplementation には紐づくクラス・メソッドが存在します。
今回はGetEntitySet の実装を行うため、「Methods」→「Inherited Methods」にある「BNKASET_GET_ENTITYSET」が対象になります。
「BNKASET_GET_ENTITYSET」を右クリックし「Redefine」を選択します。
ここで「BNKASET_GET_ENTITYSET」の内部実装コードの画面に移るので、ABAP で実装を進めることができます。
ここではODataサービスのGetEntitySet がコールされた際のインプットパラメータを駆使しながら、最終的にはBNKAのデータモデルに従ったレスポンスを「et_entityset」に渡す処理の実装を進めるイメージです。
とはいえ、今回はとてもシンプルにBNKAテーブルの上位10件をセレクトして、「et_entityset」に渡すだけの処理を以下のように実装しました。
「Insert」ボタンをクリックして以下の行を追加しています。
> SELECT * UP TO 10 ROWS FROM bnka INTO CORRESPONDING FIELDS OF TABLE et_entityset.
あとは実装結果を反映させるために「Activate」を実行します。
では、再度SAP Gateway Clientに戻ってGetEntitySet をコールしてみましょう!
うまく実装が反映されていれば以下のようにBnka のデータが取得できているはずです。
URLからも呼び出してみると、以下のようにブラウザ経由でも確認できます!
もちろん、このままではページネーションやフィルター条件の実装も無いため、中途半端なOData サービスになっていますが、実装していくための一端がイメージできるかなと思います。
CData SAP Netwaver Gateway Driver で作成したOData サービスに接続してみる
それでは最後に作成したOData サービスへCData SAP Netwaver Gateway Driver から接続してみましょう。
今回はODBC Driver を利用して接続してみますが、利用するコネクタはJDBCでもADO.NET でもCData Sync でも同じです。
https://www.cdata.com/jp/drivers/sapgateway/
CData SAP Netwaver Gateway Driver のODBC DSN 構成画面を起動して必要な情報を入力します。SAP S/4 HANA Private Cloud のライアル環境では50000ポートで公開されるようなので、そのURLおよびユーザー情報を指定します。Namespaceはsap、Service には今回作成したOData サービスの「CDATA_SAMPLE_SRV」を入力します。
これで接続テストをクリックし、以下のようにメッセージが表示されればOKです。
データモデルのタブに移動してみると、先程確認したBNKASetのオブジェクトが確認できます。
プレビュータブを表示してみると、実際にレコード10件が返却されていることが確認でき、正常にGetEntitySet がコールされていることがわかりました!
接続先のIPアドレスについて
ちなみに今回外部から接続しましたが、その際に利用するパブリックIPアドレスは「SAP S/4HANA 2023 FPS00 & SAP HANA DB 2.0」のマシンで、ポート番号は50000になっていました。
ちなみにSAP Gateway クライアントだとhosts ファイルで指定されているDNSで接続されています。
以下のようにPrivate IP アドレスが確認できます。
複数リソースの対応
OData サービスは1サービスの中に複数リソース・EntitySet をまとめることができるようになっています。
例えば以下のようにADKO のデータモデルを追加することで
CData ドライバーからは複数テーブルコールできるようになります。
参考記事
以下の記事を参考にさせていただきました! ありがとうございます!
https://qiita.com/tami/items/f49a4a6be1ffd83cc87c
https://community.sap.com/t5/application-development-blog-posts/a-step-by-step-process-to-create-odata-services-in-sap-sap-hana-system/ba-p/13515353
関連コンテンツ