当前位置: 首页 > news >正文

SAP PI之Rest adapter

一,简介

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

相关文章:

SAP PI之Rest adapter

一&#xff0c;简介 REST风格接口是以http为传输协议&#xff0c;以xml或json或text为有效负载。下图展示了REST到XI再返回的一个过程&#xff0c;一个REST接口包含的信息有&#xff1a;服务URL、URL中带的参数、http方法(post/get/put等)、http头部、body部分的有效载荷。而X…...

推荐几个Github高星GoLang管理系统

在Web开发领域&#xff0c;Go语言&#xff08;Golang&#xff09;以其高效、简洁、高并发等特性逐渐成为许多开发者的首选语言。有许多优秀的Go语言Web后台管理系统&#xff0c;这些项目星星众多&#xff0c;提供了丰富的功能和良好的代码质量。本文将介绍一些GitHub高星的GoLa…...

生成式对抗网络GAN

Generative Adversarial Nets由伊恩古德费洛&#xff08;Ian J.Goodfellow&#xff09;等人于2014年发表在Conference on Neural Information Processing Systems (NeurIPS)上。NeurIPS是机器学习和计算神经科学领域的顶级国际学术会议之一。 1. GAN在哪些领域大放异彩 图像生…...

Python如何使用Excel文件

使用Python操作Office——EXCEL 首先介绍下office win32 com接口&#xff0c;这个是MS为自动化提供的操作接口&#xff0c;比如我们打开一个EXCEL文档&#xff0c;就可以在里面编辑VB脚本&#xff0c;实现我们自己的效果。对于这种一本万利的买卖&#xff0c;Python怎么能放过…...

前端基础:回顾es6相关知识

Author note(题记)&#xff1a; ECMAscript is international standard of javascript。 ECMA 是 js的国际标准版语言。 let and const 为什么之前用var现在需要用let&#xff0c;const呢&#xff1f; 其实就是因为规范作用域的问题。var的作用域无块级 for (var i 0; i <…...

Hive条件函数详细讲解

Hive 中的条件函数允许你在查询中基于某些条件执行逻辑操作。以下是你提到的条件函数的详细讲解,包括案例和使用注意事项: IF() 功能:根据条件返回两个表达式中的一个。语法:IF(boolean_test, value_if_true, value_if_false)案例:SELECT IF(1=1, true, false); 结果为 tr…...

java应用CPU过高查找原因

用top查到占用cpu最高的进程pid 根据进程ID找到占用CPU高的线程 ps -mp 60355 -o THREAD,tid | sort -r 用 printf "%x \n" 将tid换为十六进制&#xff1a;xid printf "%x \n" 6036 根据16进制格式的线程ID查找线程堆栈信息 jstack 60355 |grep ebcb -A…...

RXJS中Subject, BehaviorSubject, ReplaySubject, AsyncSubject的区别?

在RxJS&#xff08;Reactive Extensions for JavaScript&#xff09;中&#xff0c;Subject、BehaviorSubject、ReplaySubject和AsyncSubject都是Observable的变体&#xff0c;它们用于处理观察者模式中的不同场景。以下是它们之间的主要区别&#xff1a; 1、Subject: 是一种特…...

【算法题】55. 跳跃游戏

题目 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff…...

工业企业能源管理平台,可以帮助企业解决哪些方面的能源问题?

随着全球工业化进程的加快&#xff0c;工业企业在生产经营过程中消耗的能源也越来越庞大。能源成本的上升和环境保护的压力使得工业企业对能源管理的重要性有了深刻的认识。为了提高能源利用效率、降低能源消耗、减少环境污染&#xff0c;工业企业在能源管理方面迫切需要一套规…...

LLM:Training Compute-Optimal Large Language Models

论文&#xff1a;https://arxiv.org/pdf/2203.15556.pdf 发表&#xff1a;2022 前文回顾&#xff1a; OpenAI在2020年提出《Scaling Laws for Neural Language Models》&#xff1a;Scaling Laws(缩放法则&#xff09;也一直影响了后续大模型的训练。其给出的结论是最佳计算效…...

http跟https有什么区别?

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTTPS&#xff08;HTTP Secure&#xff09;是两种不同的通信协议&#xff0c;它们在数据传输的安全性方面有明显的区别&#xff1a; 1. 安全性&#xff1a; - HTTP&#xff1a;是一种明文传输协议&#xff0c;数…...

python flask学生管理系统

预览 前端 jquery css html bootstrap: 4.x 后端 python: 3.6.x flask: 2.0.x 数据库 mysql: 5.7 学生管理模块 登录、退出查看个人信息、修改个人信息成绩查询查看已选课程选课、取消选课搜索课程课程列表分页功能 教师模块 登录、退出查看个人信息、修改个人信息录入…...

IDC机房服务器搬迁之运行了几年的服务器没关过机,今天关机下架,再上架突然起不来了,怎么快速处理?

环境 戴尔R420 服务器 1U 2台直连存储 4U CentOS 7 问题描述 IDC机房服务器搬迁之运行了几年的服务器没关过机,今天关机下架,再上架突然起不来了,怎么快速处理? 服务器上电开机就出现进入紧急模式 Welcome to emergency mode! After logging in, type “journalctl …...

基于位的权限系统

基于位的权限系统是一种利用二进制位运算进行权限管理的技术。在这种系统中&#xff0c;不同的权限被编码为2的幂次方 (例如1、2、4、8等)&#xff0c;每个权限对应一个独立的二进制位&#xff08;可想而知运算速度是非常快的&#xff09;。通过将这些权限值组合在一起形成一个…...

[AIGC] Spring Boot Docker 部署指南

Spring Boot Docker 部署指南 引言 近年来&#xff0c;容器化部署成为了越来越流行的部署方式。Docker 是目前最受欢迎的容器化平台之一&#xff0c;它提供了一种将应用程序与其依赖项打包在一起&#xff0c;并以容器的形式运行的方法。Spring Boot 是一种用于快速开发和微服…...

图像处理------亮度

from PIL import Imagedef change_brightness(img: Image, level: float) -> Image:"""按照给定的亮度等级&#xff0c;改变图片的亮度"""def brightness(c: int) -> float:return 128 level (c - 128)if not -255.0 < level < 25…...

LeetCode刷题---基本计算器

解题思路&#xff1a; 根据题意&#xff0c;字符串中包含的运算符只有和- 使用辅助栈的方法来解决该问题 定义结果集res和符号位sign(用于判断对下一数的加减操作),接着对字符串进行遍历。 如果当前字符为数字字符&#xff0c;判断当前字符的下一个字符是否也是数字字符&#x…...

Kafka生产消费流程

Kafka生产消费流程 1.Kafka一条消息发送和消费的流程图(非集群) 2.三种发送方式 准备工作 创建maven工程&#xff0c;引入依赖 <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.3.1…...

c 小熊猫 c++ IDE编译ffmpeg 设置

菜单-》运行-》运行参数->编译器->编译器配置集->链接时加入下列选项 &#xff1a; -I /usr/local/ffmpeg/include -L /usr/local/ffmpeg/lib -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lm 本机ffmpeg存储位置&#xff1a;inclu…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...