Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Sidney
Product and Topic Expert
Product and Topic Expert
本博客文章翻译自此篇英文版,是关于SAP Event Mesh在SAP业务技术平台在中国(上海)区域(也即SAP Business Technology Platform on Alibaba Cloud)的应用教程,包括一个入门级的端到端的简单动手实验。所有的代码部分都可以在这个代码仓库中找到,而理论部分主要可以参考这篇帮助文档、这项教程、这个视频系列以及这篇博客文章

SAP Event Mesh在中国(上海)区域的的产品重命名还在进行中(原产品名为SAP Enterprise Messaging)。本文章将会随着此过程的进度做相应更新。

💻 您需要准备:






    • 在SAP BTP中国(上海)区域的上的全局账户和子账户;

    • SAP Event Mesh和SAP Business Application Studio的资源权利。




 

创建服务实例和租用多租户运用程序


首先,我们前往SAP BTP主控室,进行服务、资源和安全等配置。

 

权利配置


确保您的全局账户中有SAP Event Mesh 的如下资源权利,并将其分配到对应的子账户中:




















服务 技术名称 服务计划
Event Mesh enterprise-messaging default
Enterprise Messaging enterprise-messaging-hub standard

第一个服务用于创建消息客户端服务的实例,而第二个是可供租用的多租户业务应用程序,以便用户通过Web用户洁面来管理消息传递客户端和事件目录等。



服务实例


进入您CF的组织和空间中,选择 Event Mesh 服务,default计划,创建服务实例。

在弹出的向导中,您需要填入JSON格式的服务描述符(遵循语法 Syntax for Service Descriptor),你可以复制粘贴如下文本,然后修改相应参数:

{
"emname": "<message-client-name>", // fill in your message client name
"namespace": "<your-namespace>", // fill in your namespace
"version": "1.1.0",
"options": {
"management": true,
"messagingrest": true,
"messaging": true
},
"rules": {
"queueRules": {
"publishFilter": [
"${namespace}/*"
],
"subscribeFilter": [
"${namespace}/*"
]
},
"topicRules": {
"publishFilter": [
"${namespace}/*"
],
"subscribeFilter": [
"${namespace}/*"
]
}
}
}

🔖 除了使用主控室,您还可以使用CF CLI命令行来完成以上操作。

 

服务秘钥


为了创建服务秘钥,您需要前往主控室中,选择刚才创建好的服务实例 👉 为其创建服务秘钥 👉 输入秘钥名称 👉 点击创建。

您不需要输入秘钥的内容参数,系统会自动为您创建好。现在,查看自动创建的JSON格式的内容,找到如下内容:

  • namespace 命名空间,

  • management API URI和三个 messaging API URI (尤其注意 HTTP REST协议的URI),

  • client id 客户端标识,,client secret 客户端秘钥以及token endpoint令牌端点。


稍后您将会用到它们。



 

多租户应用程序以及角色和用户分配


在主控室的“租用“页面,选择服务 Enterprise Messaging (技术名: enterprise-messaging-hub),服务计划 standard


将相应角色添加到角色集合中,并将用户(在此教程中是您自己的SAP账号)添加到角色集合中。


现在,您可以在“Event Mesh”的磁贴中,通过“转到应用程序”链接来打开 Event Mesh 业务应用程序的用户界面(Event Mesh Dashboard。您可以浏览该界面上的一些功能,比如,您可以打开您刚才创建的消息客户端,查看规则、队列等信息。

 

创建队列并且测试发布或者使用消息(通过用户界面)


创建


🎬 场景:您想要看央视春晚,尤其是里面的小品节目,但是比较忙,没办法全程守在电视机前看直播。于是希望CCTV给您发送消息,告诉您什么时候是什么节目正在上演,这样至少您稍后可以通过查看消息来查找您想看的节目。

您需要首先创建一个名为comedy的队列。在用户界面上,选择 Message Clients 页面 👉 选择消息客户端磁铁 mymessageclient 👉 选择Queues 👉 选择Create Queue 👉 在弹出窗口中,填入参数:queue name = comedy,其他参数置为默认值。


点击 Create,您将会看到队列 myorg/mymessageclient/001/category 已经被创建了,但是还没有消息在队列中。
🔖 您无需再队列名前面加上命名空间作为前缀,因为系统将会自动为您加上。

 

测试


进入测试页面,在左边,选择队列与消息客户端,在 Message Data 中填入参数,点击 Publish Message。您将会看到有通知提醒您消息已经发送,并且队列中消息的数量变为1。
📊 Message Data样例

  • Content-Type: application/json

  • Body: {"time": "20210124 21:00:00", "category": "music"}



在右边,选择队列与消息客户端,点击Consume Message。您会看到刚才发送的消息的内容,并且队列中消息的数量变为0。


 

通过API创建队列与发布和使用消息(通过Postman桌面应用程序)


🎬 场景:您的女儿也想要看春晚。她只关心她的偶像们何时出场,所以她希望CCTV能为她推送关于节目的演员的消息。

Event Mesh同时也提供了可以管理队列、队列租用的API——REST APIs for Management,以及用于发送和接收消息的API——REST APIs for Messaging

我们使用Postman的桌面应用程序来发送HTTP 请求。现在您可以回想一下您创建完服务秘钥时查看的那些URI和标识符等。

 

获取访问令牌


在与Event Mesh的服务使用API通信之前,我们需要从XSUAA处获取访问令牌(access_token)。这篇帮助文档将会指导您如何使用客户端标识和客户端秘钥,从令牌端点处获取访问令牌。

您需要在Postman里填写以下信息:



































页面
Bar Method 选择GET
Bar URL <tokenendpoint>?grant_type=client_credentials&response_type=token
Authorization Type 选择Basic Auth
Authorization Username <clientid>
Authorization Password <clientsecret>

发送请求,您将会收到 200 OK 带有访问令牌的回复,您需要在后续的请求头中带入该访问令牌:AuthorizationBearer {{access_token}}

 

创建队列


在上面给出的关于API的文档中,您可以找到用来创建队列的API  PUT /hub/rest/api/v1/management/messaging/queues/{queue}

在URL中的参数 {queue} 是经过网址编码的,并且加有命名空间作为前缀的队列全称,比如 myorg/mymessageclient/001/artist 经过编码后变为 myorg%2Fmymessageclient%2F001%2Fartist

您需要在Postman里填写以下信息:






























页面
Bar Method 选择PUT
Bar URL <management[0].uri>/hub/rest/api/v1/management/messaging/queues/{queue}
Authorization Type 选择No Auth
Headers Authorization Bearer <access_token>

请求体是可选的,如果您不提供请求体,系统将会使用QueueP模式中的默认值。

发送请求,您将会收到201 Created带有已创建队列的信息的回复。

如果您想要获取某个队列的信息,您可以通过API GET /hub/rest/api/v1/management/messaging/queues。除了Method 和Path的值不同以外,其他的参数都与创建队列的参数相同。

 

发送与接收消息


为了能用API来向一个队列发送消息,我们可以从messaging API中找到API POST /messagingrest/v1/queues/{queue-name}/messages。 在URL中的参数{queue-name} 同样应该是经过网址编码的带有命名空间作为前缀的队列全称。








































页面
Bar Method 选择POST
Bar URL <messaging[protocol=httprest].uri>/messagingrest/v1/queues/{queue-name}/messages
Authorization Type 选择No Auth
Headers x-qos 样例0
Headers Authorization Bearer <access_token>
Body raw - JSON 样例{"time": "20210124 21:00:00", "artists": [{"name": "TFBOYS"}, {"name": "Ye Zhang"}]}

在请求头中,x-qos的意思是服务质量(quality of service,QoS), 0 表示服务将尝试传递消息,并且无论消息是否已传递,都将返回代码为 204 的 HTTP 响应。1 表示的是服务以 HTTP 响应代码 204 进行响应。如果未收到 204 响应代码,则客户端负责重新尝试,直到收到响应代码 204 为止。

在请求体中,您可以选择 raw 的类型,并且输入任何内容。如果您想要传输Cloud Event,您则需采用JSON的格式。

发送请求,您将会收到204 No Content的回复,并且消息的ID会被附在回复头中。


若要从队列中接收消息,您需要使用API POST /messagingrest/v1/queues/{queue-name}/messages/consumption。您可以使用与发送消息相同的请求头,并且将请求体置空。


在代码库里的文件夹 ./apis中,您将可以找到本动手实验在Postman中使用的请求的配置文件。

 

创建队列租用并向话题发送消息


🎬 场景:如果现在央视只发送一种关于节目的消息,同时含有节目类别和演员表的信息,您和您的女儿都对这一种消息感兴趣,但不幸的是,一条消息只能被一个人消费,如果您的女儿接收到了某条消息,那么您就接收不到了。此时,您需要让央视将消息发送到一个主题中,并且您和您的女儿各创建一个队列,来订阅这个话题,这样,您和您的女儿都能收到来自央视的消息,并且两人的消费行为互不影响。

 

通过用户界面为消息 artist 创建主题


您可以前往网页端的用户界面来创建主题,也即队列租用。请注意,您填入的主题的名称应该遵循您在服务描述(service descriptor)中的规则相一致,也即,名称的前缀命名空间应该与队列的相一致。


 

向主题发送消息


您可以在messaging API中找到用来发送给主题 performance 的API POST /messagingrest/v1/topics/{topic-name}/messages








































页面
Bar Method 选择POST
Bar URL 网址编码过的 <messaging[protocol=httprest].uri>/messagingrest/v1/topics/{topic-name}/messages
Authorization Type 选择No Auth
Headers x-qos 样例0
Headers Authorization Bearer <access_token>
Body raw - JSON 样例{"time": "20210124 21:05:00", "name": "A Funny Comedy", "category": "comedy", "artists": [{"name": "Ling Jia"}], "status": "START"}

发送请求后,您将会在用户界面中看到,队列artist 的消息数量增加了1。

 

通过API为队列 category 创建主题


我们使用management API PUT /hub/rest/api/v1/management/messaging/queues/{queue}/subscriptions/{topic}.






























页面
Bar Method 选择PUT
Bar URL 网址编码过的 <management[0].uri>/hub/rest/api/v1/management/messaging/queues/{queue}/subscriptions/{topic}
Authorization Type 选择No Auth
Headers Authorization Bearer <access_token>


若主题被成功创建,您将会收到201 Created带有队列和主题信息的回复。

现在的体系结构为:


图片改编自 SAP Help Portal


 

通过API发布消息到主题并从队列消费消息


发布消息到主题,您需要在Postman中创建请求,并填入如下信息:








































页面
Bar Method 选择POST
Bar URL 网址编码<messaging[protocol=httprest].uri>/messagingrest/v1/topics/{topic-name}/messages
Authorization Type 选择No Auth
Headers x-qos 样例0
Headers Authorization Bearer <access_token>
Body raw - JSON 样例{"time": "20210124 21:00:00", "name": "Go, Amigo and Hi, Motherland Mash Up", "category": "music", "artists": [{"name": "TFBOYS"}, {"name": "Ye Zhang"}], "status": "START"}

发送消息后,您可以看到,两个队列均可接收到消息。

现在让我们来从两个队列中获取消息。


 

[选做] 在SAP BTP上开发消息生产者与消息使用者的应用程序(通过Node.js或者JAVA)


在此篇教程 Tutorial: Develop a Messaging App on SAP BTP 中,您可以学到如何开发运行在BTP上的Node.js或者JAVA消息生产者和使用者应用程序。

SAP为您提供了一系列的开发工具,例如 Node.js 包, Java 类库等等,使您能够开发可以传递消息和通信的XS-Advanced应用程序(XS Advanced 即SAP HANA Extended Application Services advanced model,能使您的应用程序运行在由SAP改良的Cloud Foundry PaaS平台上)。

 

JavaScript


想要使用JavaScript开发,您可以参考 Standard Node.js Packages for XS Advanced

  • @Sap/xb-msg: 此开发包提供了消息代理以及相关通信功能,可以支持RabbitMQ的消息代理,支持以下协议:AMQP v091, AMQP v100, MQTT v311;

  • @Sap/xb-msg-env: 此开发包提供了建立Cloud Foundry 或者XS Advanced环境下的消息客户端的相关函数;

  • @Sap/xsenv: 此包可用于简单地创建和获取XS Advance的环境变量和服务。


 

Java


想要使用Java来进行开发,您可以参考 SAP Cloud Application Programming Model(使用到的类库为com.sap.cloud.servicesdk.xbem.*),这个类库符合Java消息服务的一些标准 Java Message Service (JMS) 2.0 specification, :

  • MessagingService,

  • MessagingServiceJmsConnectionFactory,



 

SAP Cloud SDK中的与Event Mesh有关的特性已经在计划之中,其进度依赖于CAP。

 

创建Webhook (nodejs),部署到CF,并租用到队列


🎬 场景:现在,您不想要时不时地查看您的队列是否有收到节目消息,并判断该节目是否是小品,您想要创建一个webhook,来主动从队列中获取消息,并为您记录只与小品有关的节目信息。

如果我们为消息系统添加一个webhook,那么就不是消息消。在此教程中,我们只为队列 comedy创建一个webhook。


此图片改编自 SAP Help Portal


我们接下来会采用的样例改编自这个视频系列的第一部分Youtube: Diving into messaging on SAP Cloud Platform (1-8)

 

创建和部署


前往SAP Business Application Studio 👉 创建 Full Stack Cloud Application(全堆栈云应用程序) 类型的开发空间,命名为 emtester,进入开发空间 👉 使用向导创建项目 👉 选择模板和工作区 Basic Multitarget Application 👉 Start 👉 输入项目名称 webhook,完成。

您会看到系统有自动生成一些文档,请删除它们。创建一个名为 manifest.yml 的文档,复制粘贴如下内容到文档中:
---
applications:
- name: webhook
routes:
- route: <host-name>.<domain>
path: .
memory: 128M

替换应用程序名称(name)和路径(route)为您自己的值,比如,路径应为您为应用程序取的主机名(hostname)和域名(domain)的连接 webhook.exercise.sap-samples.cn40.apps.platform.sapcloud.cn.

如果您不确定,您可以使用哪个域名,您可以在Business Application Studio 中打开Terminal  👉 cf login 👉 选择目标组织和空间 👉 使用 cf domains命令列出您组织下的所有域名 👉 选择可用域名。

在Terminal 中,前往当前项目的根目录,运行 npm init 然后一直敲击回车键,使用默认值,直到最后输入OK。您将会看到,文件package.json 已被创建,并且它需要一个主页文件 index.js

用命令 npm install express body-parser来安装所需的两个 Node.js 包,express和body-parser。 
🔖 这两个包是做什么的?

express 用于为单网页应用程序、网站以及公共HTTP API提供轻巧而简装的HTTP服务器工具。

body-parser 用于在中间件中解析请求体。

在文件package.json中,我们通过在 scripts添加键值对 start 来指定初始脚本,并删除 test 最终,我们得到的文件 package.json 长这样:
{
"name": "webhook",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1"
}
}

现在,让我们来写 index.js文件,请复制粘贴如下代码:
const express = require("express")
const bodyParser = require("body-parser")

const app = express()
const PORT = process.env.PORT || 8080

app.use(bodyParser.json())

app.get('/', (req, res) => {
res.status(401).send('Hey, this is a webhook - we only receive POST!')
})

app.post('/', (req, res) => {
if(req.body.category == "comedy") {
console.log(' ', req.body)
res.status(200).send(' ' + req.body.name).end()
}
else {
console.log(' ', req.body)
res.status(200).end()
}
})

app.listen(PORT, () => console.log(` Server running on port ${PORT}`))

[可选] 如果您想要再您的本地终端中先测试一下您的应用程序,您可以在项目根目录下,运行 npm start,然后开一个新的标签页使用cURL来向localhost发送如下请求:
curl -H 'Content-Type: application/json' -d'{"time": "20210124 21:00:00", "name": "Go, Amigo and Hi, Motherland Mash Up", "category": "music", "artists": [{"name": "TFBOYS"}, {"name": "Ye Zhang"}], "status": "START"}' http://localhost:8080/

curl -H 'Content-Type: application/json' -d'{"time": "20210124 21:05:00", "name": "A Funny Comedy", "category": "comedy", "artists": [{"name": "Ling Jia"}], "status": "START"}' http://localhost:8080/


第一条指令将会使您的应用程序在控制台打印出哭脸,二第二条指令将会打印出笑脸。

接下来将您的应用程序部署到BTP上。在Terminal中,运行命令 cf push

如果要测试 webhook,使用Postman来向Webhook发送请求。


所有的关于webhook的代码可以在这个文件夹中找到 ./webhook/

 

创造webhook租用


前往网页端用户界面 👉 前往消息客户端 👉 选择webhooks 页面 👉 篡改建webhook 租用 👉 在弹出窗口中,填入队列名称,webhook的URL地址,和其他参数 👉 点击create.


激活的过程将会在消息客户端和webhook应用程序间的第一次握手,也就是第一次通信时产生。


 

发送消息到主题 performance并从webhook的日志中读取消息


再次发布两则消息到主题 performance ,消息内容参考我们在测试主题的时候发送的消息,您会发现,队列 artist 的消息数量发生了增加,然而队列 category 的消息数量仍然为零。这说明了发送给队列 category 的消息已经被webhook消费了。

前往 cf logs webhook 查看日志,您会发现,刚才发送的两则消息被webhook消费后,分别留下了两条log,一条被标记为interested,另一条则是not interested。


如果您有将您的应用程序绑定一个SAP Apppication Logging Service 的服务实例(在这篇文档您可以了解如何实现绑定),您还可以从BTP的主控室中的日志一页查看您应用程序的日志。


至此,您已经走完了SAP Event Mesh在中国(上海)区域的第一个端到端的场景。

 

参考资料


1 Comment