SAP PI之Rest adapter

发布时间:2024年01月16日
一,简介

REST风格接口是以http为传输协议,以xml或json或text为有效负载。下图展示了REST到XI再返回的一个过程,一个REST接口包含的信息有:服务URL、URL中带的参数、http方法(post/get/put等)、http头部、body部分的有效载荷。而XI内部处理中主要包含XI消息头部和body载荷。

在HTTP call转换到XI mesage时:有效负载部分会直接转移到XI的载荷,也可选择转换例如JSON格式转换为XML,而其他部分如url和operation等等会映射到预定义的XI头部变量。

二,Inbound REST service 提供REST服务

本小节我们描述一个通过PI提供REST接口服务的场景,一个外围系统通过http call调用进入到PI时,PI将选择一个sender channel处理入栈调用,下图展示了在sender channel一端使用REST适配器将接收到的HTTP call最终转化为XI消息的过程。

2.1 Channe Selection

一个HTTP call入栈时PI会根据URL、HttpOperation甚至PayloadContent来决定使用哪个sender channel。

在sender channel的Channel Selection页签配置了channel确定的一系列参数

URL :HTTP://myhost:myport/RESTAdapter/API/V2.0/{resource}/{id}?operation={opname}

url前面红色部分是固定的,所有PI提供的REST API都以此作为URL开头,后面Endpoint部分是可选的,当然还是配上比较好使得channel的dispatch更加准确。

上图Endpoint维护基本上也是固定值(上面青色这段)

还可以使用模式匹配的方式支持动态的URL(在2.3节维护橙色部分 注意绿色部分QueryString不要维护到URL pattern之中),通过{placeholder}来代替动态部分

如下两个url都会进入到同一个sender channel

…/RESTAdapter/API/V2.0/customer/123?operation=create

…/RESTAdapter/API/V2.0/order/222?operation=delete

但是下面url缺少{id},不会对应到这个sender channel

…/RESTAdapter/API/V2.0/order?operation=create

HttpOperation:http方法GET POST PUT DELETE

如果两个sender channel的endpoint部分相同,还可以根据http call使用的方法来决定分配哪个channel,如上图蓝框部分

Payload Content

还可根据Payload中部分标签的值来决定channel,如上图黄框部分,Payload为JSON或XML时给出了不同的配置框

2.2 Payload convertion

REST的负载可以是xml或者非结构化文本,但大都情况下是JSON,如果需要对负载消息进行更复杂的处理比如字段mapping,则需要将入栈JSON需要转换为XML,如果是同步接口中还要将响应的XML转换为出栈JSON。

Payload转换的配置都在sender channel的General页签下,InputMsgFormat部分是将入栈Payload转化为XI message的一些配置

DataFormat:通常REST的入栈负载格式为JSON

CharacterSet:ManualValue就是写死一个值如图UTF-8,还可从http call其他部分取到如HttpHeader、GetVariable等等

ConvertToXML:json转换为PI内部XML格式,如果不做字段mapping而将整个报文作为字符串扔给对方接口这里可不转换

AddWrapperElement:例如{"id":1,"xingming":"李四"}其两个元素都在第一层级,但是XML中只允许有且仅有一个根元素,所以这种情况下需要为XML增加一个根元素作为包裹

ElementName / ElementNamespace:勾选了上面AddWrapEle这里就必填了,这里指定ERS里面配置的MessageType及其命名空间,根据这个显式指定来生成XML根元素。

InvalidCharacter:对于不合规的element名,进行字符替代等处理

OutputMsgFormat:是用于将Response数据转换为目标格式并出栈,只有在QoS为BestEffort时才有Response

DataFormat:将XI格式的Response消息转化为何种目标格式

ConvertXMLPayloadtoJSON:不勾会把XI格式响应以字符串的形式返回给调用者吗?

StripOuterElement:对应与InputMsgFormat中的WrapperElement配置,转换时忽略XML根元素

RemoveInvalidCharacter:对应InputMsgFormat中InvalidCharacter配置

XML/JSON Namespace Mapping:该配置同时针对InputMsgFormat和OutputMsgFormat,将XML命名空间转化为JSON前缀

Custome XML/JSON Conversion Rules:只针对Response消息由XI转JSON时,下面详述:

在内部RestAdapter使用jettison库来实现两种格式的转换,默认情况下转换逻辑只是根据jettison处理器自己的优化和类型机制,没有考虑到负载所对应的MessageType中所设置的各种属性。这样转换的结果可能有时候不符合要求。

如果一个xml元素定义为一个数组,而恰好实际负载中该数组只有一行,jettison可能将其转化为非数组

如果一个xml元素定义为一个字符串,而恰好字符串的值只包含数字字符,很可能被转化为一个整数类型(json中字符串用双引号,数值不用)

假设有如下MessageType和一个真实的xml负载内容,注意这是一个response消息

MessageType

XML消息负载

在REST sender channel中使用标准配置,将会得到如下的json响应内容。该json就出现了上述问题:ID字段被解析为数值型,而MesasgeType中它是string所以应该用双引号;Property是一个数组,其应该转化为"Property":[{"Name":"hsjfew","Value":"hkhuew"}]

在sender channel中可以设置针对具体的标签使用特别的转换规则,如下图我们给标签ID指明了数据类型为string,为标签Property指明了其为数组,默认值的指定可能为了一些空值不出现的标签。

另外XML的命名空间和前缀就可以从xml中找到,命名空间的决定因素参考笔记MessageMapping操作第五小节

类型

XML元素类型。

以下类型是当前支持的:

String, Integer, Decimal, Boolean.

只要它是有效值列表中提到的值之一,就不会区分类型值的符号。

如果没有指定值,不会应用指定的XML/JSON转换指令,而是会执行默认的Jettison处理器逻辑。

String type

string

xs:string

xsd:string

Integer type

int

integer

xs:integer

xsd:integer

Decimal type

decimal

numeric

float

xs:decimal

xsd:decimal

Boolean type

bool

boolean

xs:boolean

xsd:boolean

数组类型

XML元素是否是数组的指示符。

只要它是有效值列表中提到的值之一,就不会区分类型值的符号。

如果没有指定值,数组指示符默认为false。

如果是数组:

1

true

yes

如果不是数组:

0

false

no

默认值

在XML/JSON转换失败的情况下会赋给JSON元素的值。

例如,在上面给的demo中,元素“Quantity”的值会被作为整数处理。如果原始值不能转换为整数(比如含有字母),JSON输出会得到一个默认值。在该情况下,这个值是“0”。

需要注意的是,对于默认值而言,系统不会针对在“TYPE”中指定的类型进行元素类型检查——它会被当作字符串。在这种方式下,比如,你可以指定默认值“Invalid value”给“Quantity”。系统不会提示错误,无论是在communication channel激活的时候还是REST adapter运行期间处理相关消息的时候,即便默认值和元素类型(整型)完全不匹配。记住这点,应当注意设置默认值时要保持其类型的一致性。

Any value.

下面的值有点特别:

“null”

(带引号) – 被解释为字符串“null”

null

(无引号) – 被解释为null

“”

(只有引号 – 被解释为空字符串

2.3 Extracting information from URL/Header/Payload

从URL、HttpHeader或Payload中提取值,并对应到预定义变量或者客制化变量,这些变量会称为XI消息的头部信息,在后续处理过程中使用,比如确定PI Operation/MessageType、在IntergrationBuilder配置中决定ReceiverChannel、在MsgMapping中参与运算。

配置如下图红框部分,另外URL Pattern为EndpointURL的动态部分

DynamicAtt:可选预定义的变量(如下图红箭头),也可选客制化变量(蓝箭头)

DynAttrName:如果客制化变量就要给个名字

ValueSource:值的来源:常量、URL模式站位符(下图实例)、来自QueryString的GetVariable、HttpHeader、JSON/XML元素

Value:根据ValueSource不同,可以做不同配置

对于XML负载,使用Xpath定位xml元素,如果xml有使用命名空间,也要加上前缀,默认用dfl前缀

对于JSON负载,使用点分割的元素路径如【Flight.Airline】,数组中定位直接用元素名后接方括号0开始计数

在PI的MessageMonitor中我们能够看到最终形成的头部变量,上图中红箭头所指预定义变量最终形成下图紫框中的DynamicVariable

2.4 REST operation detection

首先要将REST operation和HTTP operation看做是两件事情,通常情况下两者是一致的,但是也可以搞些怪:例如通过如下一个http call来取得id为99的customer,通过query string来指定它是一个get REST operation

HTTP POST on http://myhost:myport/customer/99?operation=FECTH

虽然http call使用的post的方法,但是转换为XI message后在Header部分我们能看到如下operation标签内容为GET

<SAP:DynamicConfiguration xmlns:SAP="http://sap.com/xi/XI/Message/30">
    <SAP:Record name="operation" namespace="http://sap.com/xi/XI/System/REST">GET</SAP:Record>
    <SAP:Record name="SourceMessageType" namespace="http://sap.com/xi/XI/Message/30/routing">
        Z_MT_GGO_CCS_1081_ORDER_REQ</SAP:Record>
    <SAP:Record name="path" namespace="http://sap.com/xi/XI/System/REST">/</SAP:Record>
    <!--...-->
</SAP:DynamicConfiguration>
2.5 Mapping to PI Interface/Operation

通常XML的入栈负载其最外层元素包含了Interface/Operation名,如果是JSON负载在转化为XML时可能需要加上这个东东。一个Sender通道可以处理多个REST URL(尤其是Dynamic url),此时需要根据入栈信息确定在XML最外层元素加上什么

Variable:就是前面2.3中涉及的预定义变量和客制化变量

Expression:固定值或Glob表达式

Operation/Namespace:在最外层XML加入节点的名字与命名空间

2.6 Send Message to PI

本阶段消息已经有Adapter Engine处理完毕,形成了XI格式消息,并发送给下一个组件处理

2.7 Error Handling

错误处理是一个可选的设置,Sender通道错误的发生比如是适配器的格式转化错误、配置错误,以及同步接口的response消息内容错误。错误的处理方式:

      • Error:记录错误日志,消息传输失败
      • Ignore Error:记录错误日志,消息传输成功
      • Custome Result:消息传递成功,指定一个Http status code和Payload返回
三,Outbound REST service 调用远程REST服务

本小节的场景:SAP erp通过PI调用一个外部REST接口,我们重点关注Receiver channel处理,它会将用适配器将XI消息转化为Http请求并发往REST服务方,在同步接口时还要将Http返回转化为XI消息。

3.1 Read XI message

通过IntergrationServer处理XI格式消息来到了ReceiverChannel,主要包括HeaderVariable和Payload

3.2 Operation Rules

与2.5小节配置相对应;输入的负载为XML格式时,适配器可以从最外层元素取得Interface/Operation名,可以用这个名字映射到DynamicVariable(可用于下一步生成DynamicURL)。下表展示了Glob表达式(红色)和固定值(绿色)两种配置形式

Operation

Namespace

Variable

Value

Customer*

http://sap.com/xi/XI/Demo/

resource

customer

*Create

http://sap.com/xi/XI/Demo/

httpoperation

POST

CustomerCreate

http://sap.com/xi/XI/Demo/

resource

customer

CustomerCreate

http://sap.com/xi/XI/Demo/

httpoperation

POST

3.3 generate Dynamic URL

在调用REST之前要确定本次调用的REST url地址

url地址可以是静态的,在下面URL pattern写死就行了。动态的url可以用占位符来替换一些动态值,替代值可以是常量、Header变量、Xpath或JSON定位元素

3.4 Determine http operation

在调用REST接口时使用的http方法,可以如下图写死,也可根据Header变量等等

3.5 Setting HTTP Header

如果REST服务方需要某些http抬头值,可以设置一个手工值或者使用占位符引用3.3小节设置的Pattern Variable值,比如有时token不放在url里面,而是放在HttpHeader

3.6 Convert Payload

涉及到请求和响应两部分的转换,如下图绿框和红框两块区域

下图示例:REST服务方要求请求负载为json格式,且其返回负载也为json格式

RequestFormat部分:将XI格式消息转化为JSON

StripOperationFromMsg:如果XI消息最外层元素为Interface/Operation信息,而REST服务端不关心该信息,可以勾选剔除

Convert XML Payload to JSON:勾选后会出现下方更多转换配置,包括图最下方Custom XML/JSON Convert Rule

ResponseFormat部分:将REST服务返回的JSON负载转化为XI格式

3.7 Calling REST service

调用远程REST服务,返回HttpStatusCode

文章来源:https://blog.csdn.net/hustliangchen/article/details/135626883
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。