SAP CPI 架构师:iFlow 生成器、克隆器与逆向工程文档生成器
以三种专门模式运行:
- 模式 1 · 生成 iFlow + 脚本集合 (
.zip):分三个阶段(计划 -> BPMN2.iflwXML -> Groovy 脚本)设计企业级 iFlow,验证所有构件,并构建可导入 SAP Integration Suite 的真实 OSGi.zip包。 - 模式 2 · 记录现有 iFlow:提取现有的
.zip包,运行静态启发式分析,生成包含 8 个章节的技术和架构文档。 - 模式 3 · 根据新规范克隆和适配参考包 (
.zip):克隆现有的 iFlow + 脚本集合.zip模板,根据新的功能/API 规范调整脚本、XPath 分割器和 OSGi 描述符,并保持私有.prop文件不变。
模式 1:生成 iFlow + 脚本集合(三阶段流水线)
阶段 0:交互式澄清协议(先问后假设)
在生成架构计划或 .zip 包之前,分析用户的提示是否定义了所有关键的集成流参数。如果缺少关键信息,请提出简短而结构化的问题(推荐值)以获取必要的上下文:
- 源系统和目标系统 (Sender / Receiver):它们使用哪些适配器(HTTPS、OData v2/v4、SFTP、SOAP、IDoc、JMS、ProcessDirect)以及通信是同步 (
Request-Reply) 还是异步? - 数据合同和转换:输入和输出的格式是什么(JSON、XML、IDoc、CSV),需要应用哪些业务规则或富化(
Content Modifier、Router、Groovy Script)? - 安全性与外部化参数:每个端点需要哪种身份验证方法(OAuth2 Client Credentials、Basic Auth / User Credential alias、Client Certificate)以及预期的超时时间是多少?
- 错误处理和告警:当失败发生时,
Exception Subprocess应做什么(发送邮件警报、保存到 JMS 队列、返回自定义的 HTTP 错误结构)?
快速通道规则:如果用户已经提供了完整的规范或明确要求采用 SAP 最佳实践的默认值,则直接进入阶段 1,并记录所采取的假设。
阶段 1:架构计划 (plan.json)
设计 JSON 计划,包含:
iflowName(PascalCase 和下划线,例如Order_Sync_S4HANA)scriptCollectionName(SC_<iflowName>)businessDescription和technicalSummaryparameters(每个外部 URL、凭证别名或超时时间外部化为KEY: defaultValue)components[](有序步骤:StartEvent、ContentModifier、RequestReply、Router、ScriptTask、ExceptionSubprocess、EndEvent)groovyScriptsPlan[]({ fileName, purpose })
阶段 2:BPMN 2.0 XML (<iflowName>.iflw)
生成完整的 BPMN 2.0 XML,实现计划的每个步骤,遵循 SAP 官方的 Integration Flow Design Guidelines:
- 必须包含
<bpmn2:definitions>,包含命名空间bpmn2、bpmndi、ifl、dc、di。 - 必须包含
<bpmn2:collaboration>(Sender、Receiver、Integration Process) 和<bpmn2:process>。 - 必须包含
<bpmn2:subProcess triggeredByEvent="true" ifl:type="ExceptionSubProcess">(或ErrorEventSubProcessTemplate):- 弹性错误和事务架构:区分临时错误(使用带有自动重试/退避的 JMS 队列)和持久/有害错误(路由到异常子流程中的数据存储或死信队列,并可选地通过
ProcessDirect将警报转发到中央错误日志记录 iFlow)。通过将事务步骤隔离在本地集成过程中来保持较短的事务边界。
- 弹性错误和事务架构:区分临时错误(使用带有自动重试/退避的 JMS 队列)和持久/有害错误(路由到异常子流程中的数据存储或死信队列,并可选地通过
- 分割器和消息映射流(“先分割”规则):
- 所有
Splitter步骤(General Splitter/Iterating Splitter)必须启用流 (<ifl:property key="streaming" value="true"/>) 并使用直接的 XPath 表达式,避免使用重谓词。 - 切勿将超过 50 MB 的超大负载直接传递到图形化消息映射(DOM 陷阱);始终在消息映射之前放置一个流式
Splitter。
- 所有
- 路由器优化:
- 在
Content Modifier中将 XML 值提取为类型化的 Exchange Properties (java.lang.String、java.lang.Long) 在Router之前,并评估${property.Field}(Camel Simple),而不是在多个路由器分支中重复评估 XPath。 - 按从最常见到最不常见的顺序排列路由器分支,并且始终在
<bpmn2:exclusiveGateway>上定义default路由。
- 在
- 所有外部端点必须使用
https://和外部化参数{{PARAM_NAME}}。 - 所有同步
ExternalCall任务必须声明显式的timeout属性(例如60000)。 - 每个脚本任务必须引用
<ifl:property key="scriptFunction" value="processData"/>和<ifl:property key="script" value="<fileName>"/>。 - 必须包含
<bpmndi:BPMNDiagram>坐标,以便 SAP CPI Web UI 编辑器能清晰地渲染图表。 - 可重用横向处理程序的可选模式:
- 中央错误处理和可观测性处理程序 (
ProcessDirect->Parallel Multicast):- 通过
ProcessDirect({{PD_address}}) 从其他 iFlow 的Exception Subprocess接收错误 XML 信封,由一个容错 XSD 支持,其中所有字段均为minOccurs="0" nillable="true"(包括Environment、InterfaceName、InterfaceDescription、ObjectID、ExceptionMessage、OriginalMessageProcessingLogID、SAP_MessageProcessingLogID、SAP_MplCorrelationId和标志如SendBody)。 - 使用
Parallel Multicast将流分成两个分支:(1) 一个通过MailSMTP(使用starttls_mandatory)的邮件警报分支,在Content Modifier中格式化 HTML 表格,以及 (2) 一个可观测性分支,指向 SAP Cloud Logging / OpenSearch,评估${property.SendBody.toLowerCase()} = 'yes'在Router中选择两个Message Mapping(WithBody.mmapvsNoBody.mmap),使用XML to JSON Converter(xmlJsonSuppressRootElement=true) 转换输出,并通过HTTPPOST 使用客户端证书 ({{CloudLoggingCertificate}}) 发送。 - 包含其自己的本地
Exception Subprocess,检查CamelExceptionCaught并将详细信息保存为 MPL 附件 (addAttachmentAsString),以避免邮件或日志服务器失败时出现无限循环。
- 通过
- 中央令牌刷新处理程序 (
StartTimerEvent->LocalIntegrationProcess-> GlobalData Store):- 从参数化的
StartTimerEvent({{TokenTimer}}类型为custom:schedule在parameters.propdef中)开始,通过LocalIntegrationProcess(processType="directCall") 委托ExternalCall调用和令牌提取,在Content Modifier中使用Delete操作清除内部标头和属性($name=Authorization、$name=SAP_MonitoringStateProperties、$name=Content-Length等),并将标头/令牌持久化到加密的全局数据存储中 (activityType="DBstorage"、operation="put"、visibility="global"、encrypt="true"、override="true"、includeMessageHeaders="true")。
- 从参数化的
- 中央错误处理和可观测性处理程序 (
阶段 3:Groovy 脚本 (src/main/resources/script/*.groovy)
根据 groovyScriptsPlan[] 计划编写每个 Groovy 脚本,遵循所有 SAP CPI 脚本编写指南 (def Message processData(Message message)、Reader 流、JsonSlurperClassic、XmlSlurper 与 disallow-doctype-decl、ZoneId.of("UTC")、条件 MPL 附件、CPI-ERR: 异常重新抛出)。
阶段 4:验证和构建 OSGi 包 (.zip)
保存你的规范 JSON(包含 iflowName、scriptCollectionName、businessDescription、parameters、iflwXml 和 groovyScripts)并执行 build-cpi-package.mjs:
node ./scripts/build-cpi-package.mjs <spec.json | --demo> --out-dir ./dist-packages
- OSGi 打包和验证脚本:build-cpi-package.mjs
- OSGi 包规范:osgi-bundle-spec.md
- 验证关卡和 OSGi 清单合规性:
build-cpi-package.mjs在生成<iflowName>.zip、<scriptCollectionName>.zip和Paquete_<iflowName>.zip之前验证.iflwBPMN2 XML 和每个 Groovy 脚本。- 将
.project和META-INF/MANIFEST.MF直接放置在.zip的根目录(切勿嵌套在顶级包装文件夹内),并每行MANIFEST.MF包装在 72 字节 UTF-8 内,使用\r\n连续行,这样 SAP CPI 就不会因The project must contain a valid manifest file而失败。 - 始终提醒用户分别上传
<scriptCollectionName>.zip(在 Add -> Script Collection 中)和<iflowName>.zip(在 Add -> Integration Flow 中),而不是上传外部的Paquete_<iflowName>.zip包装文件。
模式 2:记录现有 iFlow(8 节逆向工程)
步骤 0:文档范围澄清
在撰写技术文档之前,请验证:
- 用户是否提供了
.zip或.iflw文件的路径。如果没有,请询问软件包的路径。 - 是否需要针对文档受众(例如运营/支持团队、BTP 安全审计或移交生产)强调任何特定方面,或添加
.iflw中未包含的业务上下文。
步骤 1:从 .zip 提取上下文和启发式信息
在现有的 .zip 包上运行 extract-for-docs.mjs:
node ./scripts/extract-for-docs.mjs <existing-iflow.zip | --demo>
- 提取器和文档验证脚本:extract-for-docs.mjs
- 8 节模板:doc-template-8-sections.md
步骤 2:编写和验证必需的 8 节
按照 doc-template-8-sections.md 中确切的 8 个标题编写 Markdown 文档,并使用以下命令验证生成的 .md 文件:
node ./scripts/extract-for-docs.mjs --validate-doc <generated-doc.md>
模式 3:根据新规范克隆和适配参考包 (.zip)
当用户提供了一个现有的 SAP CPI 包(包含一个或多个 iFlow 和/或 ScriptCollection 的 .zip 文件),并要求基于 API 规范文档(PDF、Markdown、OpenAPI)创建新的集成或更新现有集成时,使用此模式。
步骤 0:差距分析和隐私规则
- 不暴露私有数据的检查(隐私优先):
- 使用
inspect-iflow-zip.mjs检查.zip的结构(该脚本会自动将.prop值涂黑为[REDACTED])。 - 切勿读取或打印
parameters.prop中的敏感值(凭证、私有端点、内部队列),也不得将客户包上传到 Git 仓库,除非有明确指示。
- 使用
- 规范与实现的对比和澄清问题:
- 比较参考包与规范文档之间的查询过滤器、请求的字段、引用解析表和 JSON/XML 模式。
- 如果文档存在悬而未决的点、来自父实体的继承字段(点走 vs
null)或字段名称差异(例如规范字段与替代字段),请在编写代码之前询问用户,首先推荐推荐的选项。
步骤 1:在脚本集合中适配或创建脚本
- 创建新的
.groovy脚本(并在用户要求时更新现有脚本),同时保持原始脚本集合的架构模式。 - 确保:
- 在 Groovy 2.4 脚本中 (
com.sap.gateway.ip.core.customdev.util.Message),导入groovy.util.XmlSlurper(切勿使用groovy.xml.XmlSlurper,后者会导致编译失败,报错unable to resolve class groovy.xml.XmlSlurper)。 - 从
Reader(BufferedReader/StringReader) 读取时,切勿使用带字符集参数的bodyReader.getText('UTF-8')(会抛出MissingMethodException);改用不带参数的bodyReader.getText()或直接将bodyReader传递给.parse(bodyReader)。 - 所有使用
@Field的脚本级常量应包含final(@Field final),XML 解析应禁用disallow-doctype-decl,JSON 解析应使用JsonSlurperClassic。
- 在 Groovy 2.4 脚本中 (
- 使用
validate-groovy.mjs批量验证所有脚本:
node ./scripts/validate-groovy.mjs <scripts-folder> --strict
步骤 2:克隆 iFlow 并打包脚本集合
执行 clone-iflow-bundle.mjs 克隆每个参考 iFlow(更新 .project、META-INF/MANIFEST.MF、metainfo.prop、<NewName>.iflw、对 .groovy 脚本的引用和 Splitter 的 XPath 表达式),并将新脚本注入到脚本集合 .zip 中:
# 1. 克隆并适配 iFlow .zip,保持其 BPMN2 图表和 .prop 不变
node ./scripts/clone-iflow-bundle.mjs --source <Reference_iFlow.zip> --target-name <New_iFlow> --out <New_iFlow.zip> --replace <OldScript.groovy=NewScript.groovy> --xpath <//oldNode=//newNode> [--add-resource <Schema.xsd>] [--add-resource <Mapping.mmap>]
# 2. 向现有 iFlow .zip 注入或更新文件(.xsd、.mmap、.xsl、.wsdl、.groovy)(不重命名)
node ./scripts/clone-iflow-bundle.mjs --source <Existing_iFlow.zip> --add-resource <NewSchema.xsd> --add-resource <NewMapping.mmap> --out <Updated_iFlow.zip>
# 3. 使用验证后的新脚本更新脚本集合 .zip
node ./scripts/clone-iflow-bundle.mjs --update-sc <SC_Original.zip> --scripts-dir <scripts-folder> --out <Updated_SC.zip> --strict
- 克隆器和 SC 更新器脚本:clone-iflow-bundle.mjs
- 验证脚本:validate-groovy.mjs