SAP CPI 架構師:iFlow 產生器、複製器與逆向工程文件產生器 是做什麼的?
以三種專門模式運作:
- 模式一 · 產生 iFlow + Script Collection (
.zip):以 3 階段(規劃 -> BPMN2.iflwXML -> Groovy 腳本)設計企業級 iFlow,驗證所有成品,並建構可直接匯入 SAP Integration Suite 的真實 OSGi.zip套件。 - 模式二 · 為現有 iFlow 產生文件:解壓現有
.zip套件,執行靜態啟發式分析,並產生包含 8 個章節的技術與架構文件。 - 模式三 · 根據新規格複製並改編參考套件 (
.zip):複製現有可運作的 iFlow + Script Collection.zip範本,根據新的功能/API 規格改編腳本、XPath 分割器和 OSGi 描述元,同時保持私有的.prop檔案不變。
模式一:產生 iFlow + Script Collection(3 階段流程)
階段 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 佇列) 和永久/有害錯誤 (在 Exception Subprocess 中路由至 Data Store 或 Dead-Letter Queue,並選擇性地透過
ProcessDirect將警報轉發至中央錯誤記錄 iFlow)。透過將交易步驟隔離在 Local Integration Processes 中,保持交易邊界簡短。
- 彈性的錯誤與交易架構:區分暫時性錯誤 (使用具自動重試/退讓機制的 JMS 佇列) 和永久/有害錯誤 (在 Exception Subprocess 中路由至 Data Store 或 Dead-Letter Queue,並選擇性地透過
- 分割器與訊息對映串流 (「先分割」規則):
- 所有
Splitter步驟 (General Splitter/Iterating Splitter) 必須啟用串流 (<ifl:property key="streaming" value="true"/>),並使用簡單的 XPath 表達式,避免使用複雜的述詞。 - 切勿將大型酬載 (> 50 MB) 直接傳遞至圖形化 Message Mapping (DOM 陷阱);務必在 Message Mapping 之前放置一個串流
Splitter。
- 所有
- 路由器最佳化:
- 在
Router之前,於Content Modifier中將 XML 值提取為具型別的 Exchange Properties (java.lang.String、java.lang.Long),並評估${property.Field}(Camel Simple),而不是在多個 Router 分支中重複評估 XPath。 - 將 Router 分支從最頻繁到最不頻繁排序,並務必在
<bpmn2:exclusiveGateway>上定義default路由。
- 在
- 所有外部端點必須使用
https://和外部化參數{{PARAM_NAME}}。 - 所有同步
ExternalCall任務必須宣告明確的timeout屬性 (例如60000)。 - 每個 Script Task 必須引用
<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 信封,由一個所有欄位皆為minOccurs="0" nillable="true"的寬容 XSD 支援 (包括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 的可觀測性分支,在Router中評估${property.SendBody.toLowerCase()} = 'yes',以選擇兩個Message Mapping(WithBody.mmapvsNoBody.mmap),使用XML to JSON Converter(xmlJsonSuppressRootElement=true) 轉換輸出,並透過帶有用戶端憑證的HTTPPOST ({{CloudLoggingCertificate}}) 發送。 - 包含其自己的本機
Exception Subprocess,該程序檢查CamelExceptionCaught並將詳細資訊儲存為 MPL 附件 (addAttachmentAsString),以避免在郵件伺服器或日誌伺服器故障時出現無限迴圈。
- 透過
- 中央令牌重新整理處理器 (
StartTimerEvent->LocalIntegrationProcess-> 全域Data Store):- 從參數化的
StartTimerEvent開始 ({{TokenTimer}},類型為custom:schedule,在parameters.propdef中),將ExternalCall和令牌提取作業委派給LocalIntegrationProcess(processType="directCall"),在Content Modifier中透過Delete動作 ($name=Authorization、$name=SAP_MonitoringStateProperties、$name=Content-Length等) 清除內部標頭和屬性,並將標頭/令牌持久化儲存到加密的全域 Data Store (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、使用 disallow-doctype-decl 的 XmlSlurper、ZoneId.of("UTC")、條件式 MPL 附件、CPI-ERR: 例外重新拋出)。
階段 4:驗證與建構 OSGi 套件 (.zip)
儲存包含 iflowName、scriptCollectionName、businessDescription、parameters、iflwXml 和 groovyScripts 的規格 JSON,並執行 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 Manifest 遵循:
build-cpi-package.mjs在產生<iflowName>.zip、<scriptCollectionName>.zip和Paquete_<iflowName>.zip之前,會驗證.iflwBPMN2 XML 和每個 Groovy 腳本。- 將
.project和META-INF/MANIFEST.MF放置在.zip的根目錄 (切勿巢狀在頂層包裝資料夾內),並將所有MANIFEST.MF行以 72 bytes 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包裝。
模式二:為現有 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>
模式三:根據新規格複製並改編參考套件 (.zip)
當使用者提供現有的 SAP CPI 套件 (包含一個或多個 iFlow 和/或 ScriptCollection 的 .zip) 並要求根據 API 規格文件 (PDF、Markdown、OpenAPI) 建立新的整合或更新現有的整合時,請使用此模式。
步驟 0:差距分析與隱私規則
- 不暴露私人資料的檢查 (隱私優先):
- 使用
inspect-iflow-zip.mjs檢查.zip的結構 (該程式會自動將.prop的值編輯為[REDACTED])。 - 切勿讀取或列印
parameters.prop中的敏感值 (憑證、私人端點、內部佇列),除非有明確指示,否則也不要將用戶端套件上傳至 Git 儲存庫。
- 使用
- 規格與實作的比對以及釐清問題:
- 比較參考套件與規格文件之間的查詢篩選器、請求的欄位、參考解析表和 JSON/XML 結構描述。
- 如果文件存在未明確定義之處、父實體繼承的欄位 (dot-walking vs
null),或欄位名稱不一致 (例如,標準欄位 vs 替代欄位),請在撰寫程式碼之前詢問使用者,並先建議首選選項。
步驟 1:在 Script Collection 中改編或建立腳本
- 建立新的
.groovy腳本 (並在使用者要求時更新現有腳本),同時維持原始 Script Collection 的架構模式。 - 確保:
- 在 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 ../sap-cpi-groovy-generator/scripts/validate-groovy.mjs <script-folder> --strict
步驟 2:複製 iFlow 並打包 Script Collection
執行 clone-iflow-bundle.mjs 以複製每個參考 iFlow (更新 .project、META-INF/MANIFEST.MF、metainfo.prop、<NewName>.iflw、對 .groovy 腳本的引用以及 Splitter 的 XPath 表達式),並將新腳本注入 Script Collection .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. 將單獨檔案 (.xsd, .mmap, .xsl, .wsdl, .groovy) 注入或更新至現有 iFlow .zip 中 (不重新命名)
node ./scripts/clone-iflow-bundle.mjs --source <Existing_iFlow.zip> --add-resource <NewSchema.xsd> --add-resource <NewMapping.mmap> --out <Updated_iFlow.zip>
# 3. 使用驗證過的新腳本更新 Script Collection .zip
node ./scripts/clone-iflow-bundle.mjs --update-sc <SC_Original.zip> --scripts-dir <script-folder> --out <SC_Updated.zip> --strict
- 複製器與 SC 更新器程式: clone-iflow-bundle.mjs
- Script Collection 包裝器: sc-packager.mjs
參考資料
- OSGi 套件規格: osgi-bundle-spec.md
- 8 章節文件範本: doc-template-8-sections.md
- 一般 XSD 參考: common-xsd-references.md