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

1. 簡介

本程式碼研究室會逐步說明如何使用 ABAP 適用的 Google Cloud SDK,從 Google Cloud Pub/Sub 主題接收事件詳細資料。我們將運用下列 Google Cloud 服務:

  • Cloud Pub/Sub
  • Cloud Shell

必要條件

gcloud pubsub topics create PUBSUB_DEMO_TOPIC

建構項目

您將建立下列項目:

  • 具有「訂閱者」權限的服務帳戶,可與 Pub/Sub API 互動。
  • ABAP 程式,用於接收及確認來自 Pub/Sub 主題的訊息。

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」IAM頁面。您建立的服務帳戶應會列出,以及已指派給該帳戶的角色。

5. 瞭解提取訂閱項目

如果是提取式訂閱項目,SAP 系統會做為訂閱端用戶端,向 Pub/Sub 伺服器發出要求來擷取訊息。訂閱端用戶端會使用 REST Pull API。

重要 API 方法

Google Cloud Pub/Sub API

  • pull:發出要求以擷取訊息。
  • 確認:向 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 Console:直接在 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 版 Google Cloud SDK 會使用 /GOOG/CLIENT_KEY/GOOG/SERVIC_MAP. 資料表。

如要維護 /GOOG/CLIENT_KEY 表格中的設定,請按照下列步驟操作:

  1. 在 SAP GUI 中輸入交易代碼 SPRO
  2. 按一下「SAP Reference 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. 建立 ABAP 報表,接收來自 Google Cloud Pub/Sub 的訊息

  1. 登入 SAP 系統。
  2. 前往交易代碼 SE38,並建立名為「Report Program」的報表程式 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。
  • 訂閱項目名稱:指定要從哪個訂閱項目擷取訊息 (PUBSUB_DEMO_SUBSCRIPTION)。
  • 訊息限制:設定單一 API 呼叫中要擷取的訊息數量上限 (在本例中為 1)。

擷取訊息:

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

處理收到的訊息:

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

確認訊息:

  • 呼叫 acknowledge_subscriptions 方法,向 Pub/Sub 傳送確認訊息,表示已成功接收訊息。這樣一來,系統就不會重新傳送這些訊息。

處理成功/錯誤:

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

關閉連線:

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

10. 恭喜

您已完成「使用 Google Cloud 的 ABAP SDK 接收 Cloud Pub/Sub 的事件」Codelab,表現優異!

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

您已解鎖 ABAP 與 Google Cloud 服務之間的新整合層級。透過下列精彩選項拓展視野:

  • 搭配 ABAP SDK for Google Cloud 使用 Translation API
  • 使用分塊上傳功能,將大型物件上傳至 Cloud Storage bucket
  • 使用 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