使用 Google Cloud 適用的 ABAP SDK,在 SAP 中接收來自 Cloud Pub/Sub 的事件

1. 簡介

本程式碼研究室會引導您使用 Google Cloud ABAP SDK,從 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'

上述指令會使用 abap-sdk-poc 做為 Google Cloud 專案的預留位置。將 abap-sdk-poc 替換為您的專案 ID。

  1. 如要確認是否已新增角色,請前往 IAM 頁面。您建立的服務帳戶應會列出,並顯示已指派給該帳戶的角色。

5. 瞭解提取訂閱

對於提取訂閱,您的 SAP 系統會充當訂閱者用戶端,並向 Pub/Sub 伺服器發出要求,以便擷取訊息。訂閱者用戶端使用 REST Pull API。

主要 API 方法

Google 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

提取訂閱項目的訊息流程

下圖顯示訂閱端用戶端與拉取訂閱之間的工作流程。

f0fc44265192f348.png

  1. 提取要求:SAP 系統 (訂閱者) 會使用提取方法,向 Pub/Sub 伺服器要求訊息。
  2. 提取回應:Pub/Sub 伺服器會傳回零或多個訊息和確認 ID。回應中訊息為零或出現錯誤,不一定表示沒有可接收的訊息。這個回應就是圖片中顯示的 PullResponse。
  3. 確認:處理訊息後,SAP 系統會使用確認方法,並附上收到的確認 ID。這樣可避免 Pub/Sub 重新傳送訊息。

6. 設定訂閱和傳送訊息

建立提取訂閱項目

  • 請執行以下 gcloud 指令,建立名為 PUBSUB_DEMO_SUBSCRIPTION 的拉取訂閱,以便接收來自 PUBSUB_DEMO_TOPIC 的訊息:
gcloud pubsub subscriptions create PUBSUB_DEMO_SUBSCRIPTION \
--topic=PUBSUB_DEMO_TOPIC

發布訊息

請選擇下列其中一種方式,將訊息傳送至 PUBSUB_DEMO_TOPIC

  • 重複使用程式:如果您有先前的程式碼研究室 中用來發布程式的程式,請使用該程式。
  • 直接發布:如要快速測試,請嘗試下列任一做法:
  • 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 端的設定。

針對驗證和連線相關設定,Google Cloud 專用的 ABAP SDK 會使用 /GOOG/CLIENT_KEY/GOOG/SERVIC_MAP. 資料表

如要維護資料表 /GOOG/CLIENT_KEY 中的設定,請執行下列步驟:

  1. 在 SAP GUI 中輸入交易代碼 SPRO
  2. 按一下「SAP Reference IMG」
  3. 依序按一下「ABAP SDK for Google Cloud」>「基本設定」>「設定用戶端金鑰」

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. 建立 ABAP 報表,接收來自 Google Cloud Pub/Sub 的訊息

  1. 登入 SAP 系統。
  2. 前往交易代碼 SE38,然後建立名為 ZDEMO_RECEIVE_CPS_EVENTS. 的報表程式
  3. 在隨即開啟的彈出式視窗中,提供下列詳細資料,然後按一下「儲存」

7c739236bedb5bf1.png

  1. 在下一個彈出式視窗中,選取「Local Object」或提供適當的套件名稱。
  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。
  • Subscription Name:指定要從中擷取訊息 (PUBSUB_DEMO_SUBSCRIPTION) 的訂閱項目名稱。
  • Message Limit:設定在單一 API 呼叫中可擷取的訊息數量上限 (在本例中為 1)。

擷取訊息:

  • 呼叫 pull_subscriptions 方法,從指定的訂閱項目擷取訊息。

處理收到的訊息:

  • 如果有訊息,程式會解碼資料、記錄內容,並傳送確認訊息。

確認訊息:

  • 呼叫 acknowledge_subscriptions 方法,向 Pub/Sub 傳送確認訊息,指出已成功收到訊息。這樣一來,系統就不會重新放送這些廣告。

處理成功/錯誤:

  • 如果收到並確認訊息,就會提供成功訊息,並針對各種失敗情況 (未收到訊息、API 錯誤等) 顯示錯誤訊息。

關閉連線:

  • 關閉與 Pub/Sub 服務的 HTTP 連線。

10. 恭喜

恭喜完成「使用 Google Cloud 專用 ABAP SDK 接收 Cloud Pub/Sub 事件」程式碼研究室!

您已成功在 ABAP 和 Google Cloud Pub/Sub 之間建立橋接!完成本程式碼研究室後,您將充分掌握事件驅動式訊息,並瞭解如何使用 ABAP SDK for Google Cloud 與 Google Cloud 服務整合。非常好!

您已成功將 ABAP 與 Google Cloud 服務整合。透過下列精彩選項拓展視野:

  • 搭配 Google Cloud ABAP SDK 使用 Translation API
  • 使用分割功能將大型物件上傳至 Cloud Storage 值區
  • 使用 ABAP SDK for Google Cloud 從 Secret Manager 擷取憑證/密鑰
  • 從 ABAP 呼叫 Vertex AI test-bison
  • 從 ABAP 呼叫 BigQuery ML

11. 清理

如果您不想繼續進行與 Google Cloud 適用的 ABAP SDK 相關的其他程式碼研究室,請繼續進行清理作業。

刪除專案

  • 刪除 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