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 Platform Trial 并安装 ABAP SDK”,设置新系统。
- 您已在 Google Cloud 项目中创建了主题
PUBSUB_DEMO_TOPIC
,并完成了 Codelab“使用 ABAP SDK 将事件从 SAP 发送到 Pub/Sub”。如果尚未创建,请使用以下命令创建:
gcloud pubsub topics create PUBSUB_DEMO_TOPIC
构建内容
您将创建以下内容:
- 具有“Subscriber”权限的服务账号,用于与 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
- pull:发起提取消息的请求。
- acknowledge:向 Pub/Sub 发送消息已成功处理的信号。
ABAP SDK for Google Cloud 等效项
- /GOOG/CL_PUBSUB_V1 -> PULL_SUBSCRIPTIONS
- /GOOG/CL_PUBSUB_V1 -> ACKNOWLEDGE_SUBSCRIPTIONS
拉取订阅的消息流程
下图显示了订阅方客户端与拉取订阅之间的工作流。
- 拉取请求:您的 SAP 系统(订阅方)使用拉取方法从 Pub/Sub 服务器请求消息。
- 拉取响应:Pub/Sub 服务器会返回 0 条或多条消息和确认 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