ABAP SDK for Google Cloud を使用して SAP の Cloud Pub/Sub からイベントを受信する

1. はじめに

この Codelab では、ABAP SDK for Google Cloud を使用して Google Cloud Pub/Sub トピックからイベントの詳細を受信する方法について説明します。次の Google Cloud サービスを使用します。

  • Cloud Pub/Sub
  • Cloud Shell

前提条件

gcloud pubsub topics create PUBSUB_DEMO_TOPIC

作成するアプリの概要

次のものを作成します。

  • Pub/Sub API を操作するための「サブスクライバー」権限を持つサービス アカウント。
  • Pub/Sub トピックからメッセージを受信して確認する ABAP プログラム。

2. 要件

  • ブラウザ(ChromeFirefox など)
  • 課金が有効になっている Google Cloud プロジェクト、または Google Cloud Platform の90 日間の無料トライアル アカウントを作成します。
  • システムにインストールされている SAP GUI(Windows または Java)。SAP GUI がラップトップにすでにインストールされている場合は、VM の外部 IP アドレスをアプリケーション サーバー IP として使用して SAP に接続します。Mac を使用している場合は、こちらのリンクから SAP GUI for Java をインストールすることもできます。

3. 始める前に

6757b2fb50ddcc2d.png

  • 次のコマンドを実行してアカウントの認証を行い、デフォルトのプロジェクトを abap-sdk-poc に設定します。ゾーン us-west4-b は例として使用されています。必要に応じて、次のコマンドのプロジェクトとゾーンを必要に応じて変更してください。
gcloud auth login
gcloud config set project abap-sdk-poc
gcloud config set compute/zone us-west4-b

4. Pub/Sub アクセス用のサービス アカウントを作成する

Subscriber ロールを持つサービス アカウントを使用することは、ABAP プログラムが Pub/Sub からメッセージを受信する最も安全な方法です。このロールでは、権限がメッセージの取得のみに制限されるため、潜在的なセキュリティの脆弱性を防ぐことができます。

サービス アカウントを作成する

必要なロールを持つサービス アカウントを作成するには、次の操作を行います。

  1. Cloud Shell ターミナルで次のコマンドを実行します。
gcloud iam service-accounts \
create abap-sdk-pubsub-subscriber \
--display-name="Service Account for Pub/Sub Subscriber"
  1. 上記の手順で作成したサービス アカウントに、必要なロールを追加します。
gcloud projects add-iam-policy-binding abap-sdk-poc \
--member='serviceAccount:abap-sdk-pubsub-subscriber@abap-sdk-poc.iam.gserviceaccount.com' \
--role='roles/pubsub.subscriber'

上のコマンドでは、Google Cloud プロジェクトのプレースホルダとして abap-sdk-poc を使用しています。abap-sdk-poc は、実際のプロジェクト ID に置き換えます。

  1. ロールが追加されたことを確認するには、[IAM] ページに移動します。作成したサービス アカウントと、そのサービス アカウントに割り当てられたロールが一覧表示されます。

5. pull サブスクリプションについて

pull サブスクリプションでは、SAP システムがサブスクライバー クライアントとして機能し、Pub/Sub サーバーへのリクエストを開始してメッセージを取得します。サブスクライバー クライアントは REST Pull API を使用します。

主な API メソッド

Cloud Pub/Sub API

  • pull: メッセージを取得するリクエストを開始します。
  • acknowledge: メッセージが正常に処理されたことを Pub/Sub に通知します。

ABAP SDK for Google Cloud の同等機能

  • /GOOG/CL_PUBSUB_V1 -> PULL_SUBSCRIPTIONS
  • /GOOG/CL_PUBSUB_V1 -> ACKNOWLEDGE_SUBSCRIPTIONS

pull サブスクリプションのメッセージのフロー

次の図は、サブスクライバー クライアントと pull サブスクリプション間のワークフローを示しています。

f0fc44265192f348.png

  1. プル リクエスト: SAP システム(サブスクライバー)は pull メソッドを使用して、Pub/Sub サーバーからメッセージをリクエストします。
  2. Pull レスポンス: Pub/Sub サーバーは、0 個以上のメッセージと確認応答 ID で応答します。メッセージがゼロまたはエラーであるレスポンスは、受信可能なメッセージがないことを示しているわけではありません。このレスポンスは、画像に示す PullResponse です。
  3. 確認応答: メッセージを処理した後、SAP システムは、受信した確認応答 ID とともに acknowledge メソッドを使用します。これにより、Pub/Sub がメッセージを再配信するのを防ぐことができます。

6. 定期購入の設定とメッセージの送信

pull サブスクリプションを作成する

  • 次の gcloud コマンドを実行して、PUBSUB_DEMO_TOPIC からメッセージを受信する PUBSUB_DEMO_SUBSCRIPTION という名前のプル サブスクリプションを作成します。
gcloud pubsub subscriptions create PUBSUB_DEMO_SUBSCRIPTION \
--topic=PUBSUB_DEMO_TOPIC

Publish Messages

次のいずれかの方法で PUBSUB_DEMO_TOPIC にメッセージを送信します。

  • プログラムを再利用する: 以前の Codelab で公開用のプログラムがある場合は、そのプログラムを使用します。
  • 直接公開: 簡単なテストを行うには、次のいずれかのオプションを試します。
  • Cloud コンソール: Google Cloud コンソール内で直接公開します。詳細については、Pub/Sub のドキュメントをご覧ください。
  • gcloud コマンド: 次のコマンドを実行します。
gcloud pubsub topics publish PUBSUB_DEMO_TOPIC \
--message='{"eventType":"SalesOrderChanged","source":"SAPDEV100","eventTime":"20240207183048","SalesOrder":1000924}'

7. クライアント キー構成を作成する

Google Cloud 側で前提条件を設定したので、SAP 側の構成に進みます。

認証と接続に関連する構成の場合、ABAP SDK for Google Cloud ではテーブル /GOOG/CLIENT_KEY/GOOG/SERVIC_MAP. が使用されます。

テーブル /GOOG/CLIENT_KEY の構成を維持するには、次の操作を行います。

  1. SAP GUI で、トランザクション コード SPRO を入力します。
  2. [SAP 参照 IMG] をクリックします。
  3. [ABAP SDK for Google Cloud] > [Basic Settings] > [Configure Client Key] をクリックします。

25871e639293b9ee.png

  1. フィールドに対して次の値を維持します。その他のフィールドは空欄のままにします。

フィールド

Google Cloud キー名

PUBSUB_SUBSCRIBER

Google Cloud サービス アカウント名

abap-sdk-pubsub-subscriber@abap-sdk-poc.iam.gserviceaccount.com

Google Cloud のスコープ

https://www.googleapis.com/auth/cloud-platform

プロジェクト ID

abap-sdk-poc

認可クラス

/GOOG/CL_AUTH_GOOGLE

8. Google Cloud Pub/Sub からメッセージを受信する ABAP レポートを作成する

  1. SAP システムにログインします。
  2. トランザクション コード SE38 に移動し、ZDEMO_RECEIVE_CPS_EVENTS. という名前のレポート プログラムを作成します。
  3. 表示されたポップアップで、次のように詳細を入力し、[保存] をクリックします。

7c739236bedb5bf1.png

  1. 次のポップアップで、[ローカル オブジェクト] を選択するか、必要に応じてパッケージ名を指定します。
  2. ABAP エディタで、次のコードを追加します。
REPORT zdemo_receive_cps_events.

TYPES: BEGIN OF ty_event_message,
         event_time  TYPE timestamp,
         event_type  TYPE char30,
         source      TYPE char30,
         sales_order TYPE vbeln,
       END OF ty_event_message.

DATA: ls_input     TYPE /goog/cl_pubsub_v1=>ty_026,
      ls_input_ack TYPE /goog/cl_pubsub_v1=>ty_001,
      ls_event_msg TYPE ty_event_message.

TRY.

    "Open HTTP Connection
    DATA(lo_client) = NEW /goog/cl_pubsub_v1( iv_key_name = 'PUBSUB_SUBSCRIBER' ).

    "Populate relevant parameters
    " Derive project id from the client object
    DATA(lv_p_projects_id) = CONV string( lo_client->gv_project_id ).
    " Name of the subscription from where we want to pull data
    DATA(lv_p_subscriptions_id) = CONV string( 'PUBSUB_DEMO_SUBSCRIPTION' ).
    " Max number of messages that will be received in 1 API call
    ls_input-max_messages = 1.

    "Call API method: pubsub.projects.subscriptions.pull
    lo_client->pull_subscriptions(
      EXPORTING
        iv_p_projects_id      = lv_p_projects_id
        iv_p_subscriptions_id = lv_p_subscriptions_id
        is_input              = ls_input
      IMPORTING
        es_output             = DATA(ls_output)
        ev_ret_code           = DATA(lv_ret_code)
        ev_err_text           = DATA(lv_err_text)
        es_err_resp           = DATA(ls_err_resp) ).

    IF lo_client->is_success( lv_ret_code ).
      DATA(ls_received_msg) = VALUE #( ls_output-received_messages[ 1 ] OPTIONAL ).
      IF ls_received_msg IS NOT INITIAL.
        "Messages published to Pub/Sub should be base-64 encoded, hence in order to get the exact message, we need to decode the data field.
        "However, attributes published to Pub/Sub should be accessible as data references.
        DATA(lv_msg) = |{ cl_http_utility=>decode_base64( encoded = ls_received_msg-message-data ) }|.
        /ui2/cl_json=>deserialize( EXPORTING json          = lv_msg
                                             pretty_name   = /ui2/cl_json=>pretty_mode-extended
                                   CHANGING  data          = ls_event_msg ).

        cl_demo_output=>new( )->begin_section( |Receive Events from Cloud Pubsub using ABAP SDK for Google Cloud|
        )->write_text( |The below event was successfully received with message ID { ls_received_msg-message-MESSAGE_ID }|
        )->write_data( ls_event_msg
        )->end_section(
        )->display( ).

        ls_input_ack-ack_ids = VALUE #( ( ls_received_msg-ack_id ) ).

        "Call API method: pubsub.projects.subscriptions.acknowledge
        "Acknowledge the messages so it is not pulled again.
        lo_client->acknowledge_subscriptions(
          EXPORTING
            iv_p_projects_id      = lv_p_projects_id
            iv_p_subscriptions_id = lv_p_subscriptions_id
            is_input              = ls_input_ack
          IMPORTING
            es_output             = DATA(ls_output_ack)
            ev_ret_code           = lv_ret_code
            ev_err_text           = lv_err_text
            es_err_resp           = ls_err_resp ).

        IF lo_client->is_success( lv_ret_code ).
          MESSAGE lv_msg TYPE 'S'.
        ELSE.
          MESSAGE lv_err_text TYPE 'E'.
        ENDIF.
      ELSE.
        MESSAGE 'No Messages were received!' TYPE 'S'.
      ENDIF.
    ELSE.
      MESSAGE lv_err_text TYPE 'E'.
    ENDIF.

    "Close HTTP Connection
    lo_client->close( ).

  CATCH /goog/cx_sdk INTO DATA(lo_exception).
    MESSAGE lo_exception->get_text( ) TYPE 'E'.
ENDTRY.
  1. レポートを保存して有効にします。
  2. レポートを実行します(F8)。

実行が成功すると、次のようなレポート出力が表示されます。

5b76e886ef79d0ba.png

9. ABAP Pub/Sub サブスクライバー コードの説明

基本的に、この ABAP プログラムは、メッセージ サブスクライバーとして Google Cloud Pub/Sub と統合されます。指定されたサブスクリプションで新しいメッセージをオンデマンドで確認し、処理してから受信を確認応答して、今後の再配信を防ぎます。

このプログラムは次の処理を行います。

手順の内訳

接続を確立する:

  • /GOOG/CL_PUBSUB_V1 クラスを使用して、Google Cloud Pub/Sub サービスへの HTTP 接続を確立します。

セット パラメータ:

  • プロジェクト ID: Pub/Sub サブスクリプションが存在する関連するプロジェクト ID を抽出します。
  • サブスクリプション名: メッセージを pull するサブスクリプションの名前(PUBSUB_DEMO_SUBSCRIPTION)を指定します。
  • メッセージの上限: 1 回の API 呼び出しで取得するメッセージの最大数を設定します(この場合は 1)。

メッセージを取得:

  • pull_subscriptions メソッドを呼び出して、指定されたサブスクリプションからメッセージを取得します。

受信したメッセージを処理する:

  • メッセージが存在する場合、プログラムはデータをデコードし、コンテンツをログに記録して、確認応答を送信します。

メッセージの確認:

  • acknowledge_subscriptions メソッドを呼び出して、メッセージの正常な受信を示す確認応答を Pub/Sub に送信します。これにより、再配信されなくなります。

成功/エラーを処理する:

  • メッセージが受信され、確認応答が送信された場合は成功メッセージを提供します。さまざまな障害シナリオ(メッセージの受信なし、API エラーなど)の場合はエラー メッセージを表示します。

接続を閉じる:

  • Pub/Sub サービスへの HTTP 接続を閉じます。

10.完了

「ABAP SDK for Google Cloud を使用して Cloud Pub/Sub からイベントを受信する」Codelab を完了しました。

ABAP と Google Cloud Pub/Sub 間のブリッジが正常に構築されました。この Codelab を完了すると、イベントドリブン メッセージングと、ABAP SDK for Google Cloud を使用して Google Cloud サービスと統合する方法について理解していることを証明できます。お疲れさまでした。

ABAP と Google Cloud サービスの間の新しいレベルの統合が実現しました。以下のオプションで視野を広げましょう。

  • ABAP SDK for Google Cloud で Translation API を使用する
  • チャンキングを使用して大きなオブジェクトを Cloud Storage バケットにアップロードする
  • ABAP SDK for Google Cloud を使用して Secret Manager から認証情報/シークレットを取得する
  • ABAP から Vertex AI test-bison を呼び出す
  • ABAP から BigQuery ML を呼び出す

11. クリーンアップ

ABAP SDK for Google Cloud に関連する追加の Codelabs を続行しない場合は、クリーンアップに進んでください。

プロジェクトの削除

  • Google Cloud プロジェクトを削除します。
gcloud projects delete abap-sdk-poc

個々のリソースを削除する

  1. コンピューティング インスタンスを削除します。
gcloud compute instances delete abap-trial-docker
  1. ファイアウォール ルールを削除します。
gcloud compute firewall-rules delete sapmachine
  1. サービス アカウントを削除します。
gcloud iam service-accounts delete \
    abap-sdk-pubsub-subscriber@abap-sdk-poc.iam.gserviceaccount.com