1. 简介
此 Codelab 将引导您使用 ABAP SDK for Google Cloud 从 Google Cloud Pub/Sub 主题接收事件详细信息。我们将利用以下 Google Cloud 服务:
- Cloud Pub/Sub
- Cloud Shell
前提条件
- 确保您有权访问安装了 ABAP SDK for Google Cloud 的 SAP 系统。
- 您可以参考 Codelab“在 Google Cloud Platform 上安装 ABAP 平台试用版并安装 ABAP SDK”来设置新系统。
- 您已在 Google Cloud 项目中创建了主题
PUBSUB_DEMO_TOPIC,这是 Codelab“使用 ABAP SDK 将事件从 SAP 发送到 Pub/Sub”的一部分。如果未创建,请使用以下命令创建:
gcloud pubsub topics create PUBSUB_DEMO_TOPIC
构建内容
您将创建以下内容:
- 具有“订阅者”权限的服务账号,用于与 Pub/Sub API 互动。
- 用于接收和确认来自 Pub/Sub 主题的消息的 ABAP 程序。
2. 要求
- 浏览器,例如 Chrome 或 Firefox。
- 已启用结算功能的 Google Cloud 项目,或创建 Google Cloud Platform 90 天免费试用账号。
- 您的系统中已安装 SAP GUI(Windows 或 Java)。如果您的笔记本电脑上已安装 SAP GUI,请使用虚拟机的外部 IP 地址作为应用服务器 IP 连接到 SAP。如果您使用的是 Mac,还可以安装此链接中提供的 SAP GUI for Java。
3. 准备工作
- 在 Google Cloud 控制台的项目选择器页面上,选择或创建一个 Google Cloud 项目(例如:
abap-sdk-poc)。 - 确保您的 Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能。如果您使用的是90 天免费试用账号,请跳过此步骤。
- 您将使用 Cloud Shell,它是在 Google Cloud 中运行的命令行环境。在 Cloud 控制台中,点击右上角的激活 Cloud Shell:

- 运行以下命令,以针对您的账号进行身份验证并将默认项目设置为
abap-sdk-poc。以地区us-west4-b为例。如有需要,请根据您的偏好在以下命令中更改项目和可用区。
gcloud auth login
gcloud config set project abap-sdk-poc
gcloud config set compute/zone us-west4-b
- 在之前的 Codelab“向 Pub/Sub 发送事件”中,您必须已启用 Pub/Sub API、创建主题并向 Pub/Sub 发布消息。
4. 创建用于 Pub/Sub 访问的服务账号
使用具有 Subscriber 角色的服务账号是 ABAP 程序从 Pub/Sub 接收消息的最安全方式。此角色将权限限制为仅可检索消息,从而防范潜在的安全漏洞。
创建服务账号
如需创建具有所需角色的服务账号,请执行以下步骤:
- 在 Cloud Shell 终端中运行以下命令:
gcloud iam service-accounts \
create abap-sdk-pubsub-subscriber \
--display-name="Service Account for Pub/Sub Subscriber"
- 现在,向在上一步中创建的服务账号添加所需角色:
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。
- 如需验证是否已添加角色,请前往 IAM 页面。您创建的服务账号应会列出,并显示已为其分配的角色。
5. 了解拉取订阅
对于拉取订阅,您的 SAP 系统充当订阅者客户端,并向 Pub/Sub 服务器发起请求以检索消息。订阅方客户端使用 REST Pull API。
关键 API 方法
Google Cloud Pub/Sub API
- 拉取:发起提取消息的请求。
- 确认:向 Pub/Sub 发出信号,表明消息已成功处理。
ABAP SDK for Google Cloud 等效项
- /GOOG/CL_PUBSUB_V1 -> PULL_SUBSCRIPTIONS
- /GOOG/CL_PUBSUB_V1 -> ACKNOWLEDGE_SUBSCRIPTIONS
拉取订阅的消息流
下图显示了订阅者客户端与拉取订阅之间的工作流程。

- 拉取请求:您的 SAP 系统(订阅者)使用拉取方法从 Pub/Sub 服务器请求消息。
- 拉取响应:Pub/Sub 服务器会返回零条或多条消息以及确认 ID。包含零条消息或包含错误的响应并不一定表示没有可接收的消息。此响应是 PullResponse,如图所示。
- 确认:处理完消息后,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 表中的配置,请执行以下步骤:
- 在 SAP GUI 中,输入事务代码 SPRO。
- 点击 SAP 参考 IMG。
- 点击 ABAP SDK for Google Cloud > 基本设置 > 配置客户端密钥。

- 针对相应字段保持以下值。将其他所有字段留空。
字段 | 值 |
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 的消息
- 登录您的 SAP 系统。
- 前往事务代码
SE38并创建一个名为ZDEMO_RECEIVE_CPS_EVENTS.的报告程序 - 在随即打开的弹出式窗口中,提供如下所示的详细信息,然后点击保存。

- 在下一个弹出式窗口中,选择本地对象或提供软件包名称(视情况而定)。
- 在 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.
- 保存并启用报告。
- 执行报告 (F8)。
成功执行后,您应该会看到如下所示的报告输出:

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
删除单个资源
- 删除计算实例:
gcloud compute instances delete abap-trial-docker
- 删除防火墙规则:
gcloud compute firewall-rules delete sapmachine
- 删除服务账号:
gcloud iam service-accounts delete \
abap-sdk-pubsub-subscriber@abap-sdk-poc.iam.gserviceaccount.com