抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

最近一直在做CPI相关的开发,这里记录下通过Web Service方式发布CPI接口的过程,以供后面复习参考。这里先介绍下如何通过SAP发布的Web Service服务来配置CPI然后由CPI发布由外围系统调用的接口。后面会再介绍如何配置调用对方接口的CPI内容和其他方式发布接口的CPI配置方式。最后会再系统性的介绍下CPI里面的各种组件和功能。先把坑挖好,哈哈哈。

通过Web Service发布CPI接口

一、CPI 介绍

如果有使用过PO中间件的话,其实就更容易理解这个BTP的服务了。CPI本质就是云端的中间件服务,和PO的指责一样。但是无论是在配置接口还是做相关映射等操作都比PO要简洁的多。此外如果你对JavaScript也比较了解的话,那么对于CPI接口中的脚本还有自定义配置功能就更容易上手了。不过不会也没关系,因为CPI的官方有提供专门的参考代码,可以直接使用,都是可以满足日常对日志管理的需求的。

对于没有使用过PO或者对中间件技术不了解的同事,这里讲解下中间件的作用和信息流程,方便你对中间件有一个大概的了解。

中间件是位于系统软件和用户应用软件中间的一个软件系统,所以被称之为中间件。而它的主要作用是处理由系统软件和用户软件交互时产生的各类消息和请求。当这些消息和请求中有很复杂或需要特殊处理的内容时,则可以在中间件对这些内容进行处理。比如SAP端发布了一个接口,用来接收数组形式的JSON串数据,但是对方系统发送的JSON报文内容很多且命名等各种结构与SAP均不相同。此时就可以在中间件对外围系统的JSON做映射。只将SAP需要的数据传递到SAP即可。而当外围系统的JSON结构发生变化时也只需要重新在中间件配置映射结构即可,而不需要对SAP端的内容进行修改。同理反过来也是一样的。

以SAP与其他外围系统之间的数据交互关系为例子,可以使用下图对系统软件、用户应用软件和中间件进行简单理解。

1.CPI中间件数据交互

二、SAP 端发布Web Service服务

1.创建远程调用函数

(1)设置函数的远程属性

2.创建远程调用的函数模块

(2)设置函数参数

此处建议将所有参数都设置为可选的,然后将所有的必输校验通过代码的形式书写。不然当对方在调用接口时,传入参数没有必输的内容时会在SAP的Web Service端报500。而且这个报错是不会进入程序的所以只能通过CPI和Web Service的日志管理进行查看。不利于对接口日志的管理和排查。

3.远程函数的参数 4.远程函数的参数_单独的输出参数

(3)编写调用逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
FUNCTION YSFLIGHT_DEMO_01.
*"----------------------------------------------------------------------
*"*"本地接口:
*" EXPORTING
*" VALUE(EV_CODE) TYPE CHAR01
*" VALUE(EV_MESSAGE) TYPE CHAR255
*" TABLES
*" IT_CARRID STRUCTURE TYP_F_CARRID OPTIONAL
*" IT_CONNID STRUCTURE TYP_F_CONNID OPTIONAL
*" IT_FLDATE STRUCTURE TYP_F_FLDATE OPTIONAL
*" ET_SFLIGHT STRUCTURE SFLIGHT OPTIONAL
*"----------------------------------------------------------------------

SELECT *
FROM SFLIGHT
WHERE CARRID IN @IT_CARRID
AND CONNID IN @IT_CONNID
AND FLDATE IN @IT_FLDATE
INTO CORRESPONDING FIELDS OF TABLE @ET_SFLIGHT.
IF SY-SUBRC EQ 0.
EV_CODE = 'S'.
EV_MESSAGE = TEXT-S01."查询成功
ELSE.
EV_CODE = 'E'.
EV_MESSAGE = TEXT-E01."未查询到数据
ENDIF.

ENDFUNCTION.

2.配置企业服务

(1)新建企业服务

在程序的源代码界面按照图中所示的内容配置企业服务对象。

5.为函数模块创建企业服务

(2)设置企业服务的名称

这里依然和普通的程序命名方式一致,必须要使用Z或Y开头的名称。这次就和函数模块的名称一致了。设置完成之后点击继续按钮进入下一步。

6.企业服务的函数名称

(3)选择函数模块

此处因为我们是直接在函数模块界面创建的企业服务,所以这里就自动帮我们选择好了。直接选择下一步即可。

7.设置企业服务的名称

(4)设置服务的认证方式

这里可以选择的认证方式有四种,但是这里就不介绍了。详细的可以参照我之前写的发布Web Service接口的文章。这里选择不需要认证方式(图中的选择)然后下一步。

8.选择认证方式

(5)绑定包与请求编号

9.绑定包与请求号

(6)配置完成企业服务

配置完上一步点击继续之后就会来到下面的界面。此时就将企业服务全部配置完成了。

10.企业服务配置完成

点击完成之后就会跳转到代理配置界面,如下图所示。此时该服务的状态还是新建的,所以需要激活它。

11.激活企业服务

将上面的企业服务对象激活完成之后,在SAP端的所有操作就全部结束了。

3.配置Web服务

(1)打开Web服务页面

在SAP的导航界面输入事务代码:SOAMANAGER。进入Web服务配置界面。

12.Web 服务导航界面事务代码

输入后等待一会,等待SAP弹出企业服务浏览器页面。部分浏览器或许会提示该网址不安全,点击详细信息 –> 转到此网页即可。

13.打开Web服务配置页面

进入后会需要你登录SAP系统,输入当前系统的账号密码登录即可。

14.登录界面

(2)查找Web服务

通过浏览器登录页面后会弹出下面所示的服务配置页面。选择Web 服务配置功能。

15.Web服务配置页面

(3)查找企业服务

点击上面的Web 服务配置按钮后会进入下面的页面。在对象名称输入框中输入刚刚在SAP创建的企业服务名称YSFLIGHT_DEMO_01然后按下回车按钮搜索在SAP创建的企业服务。

16.查询企业服务

(4)创建服务对象

点击上面查询到的服务对象,进入到下面的服务对象界面。因为是新建的企业服务对象,所以列表是空的。点击图中的创建服务按钮,创建服务对象。

17.创建服务界面

(5)定义服务名称与绑定名称

此处是定义服务的名称方便区分用的,我们使用和Function 一样的名称和描述内容。定义完成上面的内容之后点击下一个按钮进入下一步。

18.定义服务名称

(6)配置接口的协议与验证

我们的传输级别安全选择**SSL(http)**,不过这个可以根据自己接口的需求来定义,选择这个从接口的角度来讲更安全,但是在使用时需要证书。

在最下面还有个传输通道验证,我们选择用户标识/密码。这样对方在使用接口时就需要输入可以登录SAP系统的账号和密码才可以使用该接口。

19.传输协议与验证方式

(7)完成配置发布服务

到这一步默认直接点击完成就可以了,因为后面就没有需要我们配置的东西了。

20.完成配置服务

(8)获取接口的WSDL地址

点击完成之后可以看到在刚刚创建服务的界面会多出下面的界面。点击图中红框圈中的按钮,可以查看接口的WSDL地址。

21.完成配置界面

我们拿到这个地址后,在后续配置CPI时就可以根据这个地址帮助CPI快速定位到SAP中的接口。

22.获取接口发布的WSDL地址

三、配置CPI端接口

1.进入CPI配置界面

这个可以问你们的Basis要一下CPI接口的配置地址,由他提供地址给你们,然后你再配置。进入CPI的地址一样需要账号登录,登录之后会看到下面的界面。

23.登录的CPI配置页面

2.选择CPI的包

点击图中红框圈中的列表按钮(设计),打开CPI配置界面。

打开的列表界面会列出所有的Package,你需要选择一个Package存放CPI的接口内容。这个和SAP一样,如果没有新建一个即可。

24.Package列表

然后打开存放CPI对应的Package,打开部件页签点击右上角的编辑按钮

25.编辑Package

3.新建iFlow

按照图中红框圈中的对象新建iFlow对象。

26.新建iFlow对象

4.填写iFlow名称与描述

填写iFlow的名称和描述,因为我们是新建的对象,所以点击图中红框圈中的添加并在编辑器中打开。直接对该接口进行操作,如果之点击添加,则还需要你在部件页签中查找到你新建的这个接口然后在编辑它。

27.填写iFlow名称与描述

5.编辑iFlow

在打开的界面可以看到由五个元素。分别是:

  • Sender:发送方
  • Integration Process:集成过程,可以理解成接口对消息和日志管理的流程图,所有的操作都是按照箭头和图标来操作的。
  • Start:接口流程的开始节点
  • End:接口流程的结束节点
  • Receiver:接收者
28.iFlow编辑界面

如果要操作iFlow对象请点击右上角的编辑按钮,CPI在配置的时候很多时候进入的界面都是Display的状态,如果要操作对象基本都需要点击编辑按钮。

6.设置CPI接口后缀

第一步需要设置CPI的接口URL后缀,可以简单理解成是接口对外的名称。外围系统可以根据CPI的接口前缀地址 + CPI接口后缀调用对应的接口地址。

设置的过程其实是从Sender对象开始拉出一条连接Start对象的箭头。然后等待弹框,在弹框中选择调用接口的方式。我们这边选择接口的调用方式是HTTPS。如果是异步接口此处需要选择JMC对象,这个后面再说。设置完接口的调用方式之后双击对象间的连线会在界面的下面弹出一个属性框。点击Connection页签在Address中填入接口后缀,在User Role中填入权限角色,这个角色在什么位置我在下面介绍。

在填写适配器属性的时候我勾选掉了最下面的CSRF Protected。如果使用默认的勾选这个接口就只能通过POST的方式进行访问,如果取消勾选则可以使用POSTGET两种方式调用接口。

29.设置CPI接口的URL后缀

User Role中填写的集成流调用者在下面的路径中查看。该对象一般是默认的,在CPI初始化完成后就会有这样一个对象。

30.查看集成流调用用户名

7.添加内容修正符[可选]

(1)作用

这个组件的作用是用来对请求的内容如Header、Body等内容做一些整体的处理。或是定义一些用于在脚本中访问的全局变量。

(2)添加内容修正符

在下面的配置中,Message Header中设置的变量是可以直接在脚本中使用的,而在Message Body中则是对消息体中的Body部分做一些处理。例如本次示例中我们在传入的报文外围添加了下面的内容。在Message Body中的内容请一定注意上面的Type要选择为Expression。如果你将类型选择为Constant则报文的整体内容就和你写的内容一致了。可理解成将传进来的报文一整个替换为你写在文本框的内容。

31.内容修正符
1
2
3
4
{
"urn:YSFLIGHT_DEMO_01":
${body}
}

效果后面在日志管理的时候可以通过附件的内容查看,等后面测试的时候再演示效果。

8.添加记录日志用脚本

(1)作用

标题说的是功能,但其实这个组件是用来编写JS脚本用的。只不过最常用的是用来将传入传出的消息头和消息体保存成附件记录在监控器中。

SAP官网在脚本对象中留下了参考用的网址,在其中有保存消息为附件的模板代码。可以直接拿过来使用。

(2)官网参考网址

① 官网地址来源

新建一个脚本文件,打开之后就可以开头找到两个网址了。

32.官网参考地址
② 脚本用例

脚本用例 | SAP Help Portal

33.脚本用例网址
③ SCRIPT API

SCRIPT API

34.API网址

(3)添加日志脚本

① 添加脚本组件

继续在内容修正符的后面点击加号按钮,添加脚本组件。

此处有个注意事项,在下面最后一幕,脚本的Processing页签中有一个Script Function的输入项。该选项代表优先执行脚本中的那个方法名,例如你输入request,则程序会在其中寻找是否存在这个名称的Function。如果存在就执行这个Function,不存在CPI接口就会挂掉。

35.添加CPI日志记录脚本
② 脚本日志代码

这段代码就是直接从脚本用例 | SAP Help Portal网站中的将信息添加到消息处理日志内容。修改下附件记录的文件名称为Request01(这个名称可以自定义)。

1
2
3
4
5
6
7
8
def Message processData(Message message) {
def body = message.getBody(java.lang.String)
def messageLog = messageLogFactory.getMessageLog(message)
if (messageLog != null) {
messageLog.addAttachmentAsString('Request01', body, 'text/plain')
}
return message
}

9.添加转换器

(1)添加转换器

此处需要看你们和外围系统商议的报文结构是什么,但是从CPI到SAP的数据传输形式一般是XML形式的。所以转换器的类型一般都是 TO XML。但是目前绝大多数的接口基本都是JSON数据格式的,所以在传入的报文结构中转换器基本都是JSON TO XML

本文介绍一种动态映射SAP字段与外围系统报文的方式。这种方式有如下特征:

  • 报文的字段名和SAP的参数名称完全一致,并且字段名必须全部大写(如果传递的报文有小写字段名会映射不到值);
  • 当SAP端参数结构发生变化时,只需要在SAP GUI中的企业服务端右键对应的企业服务对象使用“一致性检查”即可;
  • CPI需要在最终的报文外层另包一层用来指向SAP端哪一个RFC的指向,参考内容修正符中Message Body中的内容。
36.添加转换器_Request

上面填写的内容如下:

JSON Prefix XML Namespace
urn urn:sap-com:document:sap:rfc:functions
soapenv http://schemas.xmlsoap.org/soap/envelope/

(2)设置CPI的运行时配置

设置完上面的内容之后就可以不设置Mapping组件了。后续还需要再设置下接口的运行时配置,内容如下:

37.设置接口的映射命名空间
1
xmlns:urn=urn:sap-com:document:sap:soap:functions:mc-style;xmlns:n0=urn:sap-com:document:sap:rfc:functions

10.Mapping组件(本次不涉及)

通过Mapping组件设置字段映射内容的配置方式我后续会放在通过CPI配置调用外围系统的接口配置中介绍。本次主要介绍不需要配置Mapping组件的接口配置。

11.配置转换后的日志文件

再编写一个脚本文件用来记录经过转换后的XML文件,用作记录。此处是为了排查万一由于转换的问题引起的BUG时,能通过两边的对照快速定位和解决问题。如果只记录传入的JSON报文的话,后续转换出现问题就不好排查了。配置方式其实和上面的第8项添加记录日志用脚本一致,只是需要修改下保存的日志附件名称。

(1)添加组件

38.记录转换为XML的脚本文件

(2)组件代码

1
2
3
4
5
6
7
8
9
10
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
def body = message.getBody(java.lang.String)
def messageLog = messageLogFactory.getMessageLog(message)
if (messageLog != null) {
messageLog.addAttachmentAsString('Request_XML', body, 'text/plain')
}
return message
}

12.添加请求答复组件

(1)组件介绍

该组件可以理解成调用组件,他分别有三个通路。一个通路是接口调用时传入的请求信息,一个通路是调用接收者(也就是正式调用接口),另一个通路就是接口返回的通路。在该通路和传入的通路一样可以对返回的信息进行格式转换或记录日志文件等。

该组件本身并无什么属性设置,他的作用主要就是做一个类似于中转的流程。

39.请求调用三通路说明

新建请求答复组件并设置CPI调用的适配器类型调用的接口地址。这里因为是外围系统调用我们的接口所以此处调用的接口地址就是我们上面发布的Web Service接口的WSDL地址。需要稍微变更一下,因为前面的内容太长了,可以使用域名代替。

(2)查看SAP主机的域名与端口

SAP系统的域名与接口可以使用事务代码:SMICM

40.查看SAP系统的域名与端口号_事务代码

点击上面红框圈起来的按钮会进入到下面的页面中。页面中主机名就是域名。

41.查看SAP系统的域名与端口号

(3)查看CPI上的域名与端口号

打开BTP平台上的云连接器页签。红框圈中的部分就是CPI上使用的域名与端口。

42.查看CPI端域名与端口
1
2
3
4
5
-- Web Service 的WSDL
http://***********:8000/sap/bc/srt/wsdl/flv_10002A111AD1/bndg_url/sap/bc/srt/rfc/sap/ysflight_demo_01/100/ysflight_demo_01/ysflight_demo_01?sap-client=100

-- CPI 域名替代后的WSDL
http://******qas:44300/sap/bc/srt/rfc/sap/ysflight_demo_01/100/ysflight_demo_01/ysflight_demo_01

(4)添加组件

添加完成SOAP的适配器后需要设置适配器中的属性。

  • Address:调用的接口地址
  • Proxy Type:指定使用的代理类型。
    • On-Premise:本地部署
    • Internet:网络部署
  • Location ID:BTP上配置的SAP服务器名称
  • Authentication:接口调用的权限认证方式
  • Credential Name:可理解成调用接口时连接对方系统的账号
  • **Timeout (in ms)**:接口的请求等待时长,单位为毫秒,默认为60秒一分钟时间。
43.创建请求回复

(5)Credential Name

下面介绍下如何创建和查找接口权限认证中的Credential Name。上面介绍了这个是用来认证调用接口系统的账号信息。一般是在监控器安全材料中维护的。

44.创建和查看调用接口的权限认证账号

因为是和SAP系统做连接的,所以一般最常用的连接方式就是和SAP系统的用户凭据类型的账号。这个其实就是SAP系统的系统账号。

45.账户界面截图

创建的时候只需要起一个在CPI端可以引用的对象名称,选择安全材料的类型和用户名、密码即可。如下图所示。

46.创建和修改权限认证账户

13.记录接口调用返回的Response

(1)添加日志记录脚本

47.接收接口返回的报文内容

(2)日志脚本代码

1
2
3
4
5
6
7
8
9
10
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
def body = message.getBody(java.lang.String)
def messageLog = messageLogFactory.getMessageLog(message)
if (messageLog != null) {
messageLog.addAttachmentAsString('Response', body, 'text/plain')
}
return message
}

14.设置格式转换器

(1)设置转换器

因为从SAP端返回的数据格式依然是XML形式的,但是对方系统接收的时候是需要JSON格式的数据。所以此处还需要再对数据做一次格式转换。并且因为我们的返回数据中数据是多条,所以对返回的JSON报文设置一个用来标识数组的字段结构。一般这种结构的名称是item。所以在配置XML Element时需要根据返回的XML结构内容定义一下数组结构。

48.设置返回参数的格式转换器

(2)返回JSON数组设置

XML Element添加的内容如下,设置时请注意大小写。映射时字段都是严格遵守大小写的。

1
2
3
4
/n0:YSFLIGHT_DEMO_01Response/ET_SFLIGHT/item
/n0:YSFLIGHT_DEMO_01Response/IT_CARRID/item
/n0:YSFLIGHT_DEMO_01Response/IT_CONNID/item
/n0:YSFLIGHT_DEMO_01Response/IT_FLDATE/item

这里来介绍一下如何确定XML Element里面的内容。首先是n0这一部分,这个是urn:sap-com:document:sap:rfc:functions这一部分的简略写法。而这一部分设置的内容在上面的第9项第(2)小项 设置CPI的运行时配置。这个地方的命名空间映射分两段,前面的一段是传入数据的映射,后面的一端是传出数据的映射。

49.设置返回报文中的数组开头内容n0

其余的属性都很好理解,内容如下:

  • YSFLIGHT_DEMO_01Response:这个后面的Response是固定的,一段拼接在RFC名称后面的文本,请注意第一个字母是大写。YSFLIGHT_DEMO_01这个就是SAP端RFC的名称了;
  • ET_SFLIGHT:需要转换为JSON数组的参数名称。这个其实就是上面新建RFC是的表参数名称,这几个表参数都是需要转成JSON数组形式的,所以这里设置了四个对象。
  • item:数组字段名,固定名称。

15.发布接口

(1)完整接口流程

50.完整CPI接口流程配置图

(2)发布接口

前面查看部署状态时,在你点击部署按钮之后多等待一段时间。待其显示已启动状态后,点击导航至“管理集成内容”

部分时候接口的地址需要多等待一段时间刷新后才会出来,所以一开始连续刷新没有接口地址也是正常的现象。

51.部署CPI接口

(3)其他查看接口地址的方式

也可以在监控器的管理集成内容界面查看到上面的内容。具体位置如图中红框所示的内容。

52.查看接口地址

四、测试CPI接口

1.POSTMAN测试工具

我们使用POSTMAN工具使用上面获取到的CPI地址,输入报文进行测试。

53.POSTMAN测试工具

这个时候我们发现他返回了状态码401,这个代表的其实是没有进行权限认证。接下来我介绍如果设置这个认证对象。

2.接口权限对象

我们点击图中的Authorization页签,选择接口认证类型为Basic Auth。然后在右侧输入CPI的认证账号和密码。

54.CPI接口认证界面

3.查询权限账号

这个账号信息需要取BTP平台进行确认。通过BTP的实例和租用页签查看相关的内容。因为我这边没有有权限的账号无法查看,所以我这边就只在这里提一下。账号也可以直接向公司的Basis要。

55.查看权限账户信息

4.发送请求

输入完成之后再次回到原来的Body页签中,发送请求。可以看到接口返回的状态码是200,代表接口创建成功。但是没有查询到数据,所以几个对象都是空的。

56.请求结果

5.查看CPI的日志管理

首先进入CPI的监控器界面,然后选择所有部件。

57.查看CPI接口日志管理_监控器界面 58.CPI接口的日志界面介绍

6.查看接口日志

(1)传入的报文 Request01

59.查看传入Request01报文

(2)将传入报文转化为XML

60.转换后的传入报文_XML

(3)返回的报文

因为我们是记录了没有经过格式转换的接口返回值,所以此处是XML的形式,如果想要查看返回的JSON内容可以考虑将日志记录脚本移动到XML TO JSON转换器之后,或在转换器之后再添加一个日志记录脚本。

61.返回的报文_XML

以上就是通过Web Service发布的CPI接口的全部流程了,这种配置方式是最常用的也是最简单的一种接口配置方式。其实其中还应该有CPI端异常后的处理方式。但这部分内容我决定后面再单独做一篇记录用来讲解CPI的异常处理。

评论