使用适用于 Google Cloud 的 ABAP SDK 从 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

构建内容

您将创建以下内容:

  • 具有“Subscriber”权限的服务账号,用于与 Pub/Sub API 交互。
  • 用于接收和确认来自 Pub/Sub 主题的消息的 ABAP 程序。

2. 要求

  • 浏览器,例如 ChromeFirefox
  • 已启用结算功能的 Google Cloud 项目,或为 Google Cloud Platform 创建 90 天免费试用账号
  • 系统中安装了 SAP GUI(Windows 或 Java 版)。如果您的笔记本电脑上已安装 SAP GUI,请使用虚拟机外部 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 服务器会返回 0 条或多条消息和确认 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 发送消息:

  • 重复使用您的程序:如果您有要发布的上一个 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 > 基本设置 > 配置客户端密钥

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. 在下一个弹出式窗口中,选择本地对象或根据需要提供软件包名称。
  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. 恭喜

恭喜您完成了“使用 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 服务之间的全新集成。利用以下令人兴奋的选项拓展您的视野:

  • 将 Translation API 与 ABAP SDK for Google Cloud 搭配使用
  • 使用分块将大型对象上传到 Cloud Storage 存储分区
  • 使用 ABAP SDK for Google Cloud 从 Secret Manager 检索凭据/密钥
  • 从 ABAP 调用 Vertex AI test-bison
  • 从 ABAP 调用 BigQuery ML

11. 清理

如果您不想继续学习与 ABAP SDK for Google Cloud 相关的其他 Codelab,请继续进行清理。

删除项目

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