SAP Restful ABAP Programming 程式設計模型的 Action 實現和雲端除錯介紹
筆者之前的文章如何使用 Restful ABAP Programming 程式設計模型開發一個支援增刪改查的 Fiori 應用,已經對 SAP Restful ABAP Programming 程式設計模型(以下簡稱 RAP)進行了一個最基本的介紹。
我們簡單回顧一下之前文章的內容:在SAP雲平臺ABAP程式設計環境裡建立了一個Z表,然後基於這張自定義資料庫表建立了CDS view,基於該view建立Service Definition,把view暴露成服務,然後通過Behavior Definition實現對Z表的增刪改查。
雙擊Service Binding裡的TravelProcessor或者右鍵選單裡選擇Open Fiori Elements App Preview, 就可以訪問Fiori應用。
稍稍有點經驗的 SAP 顧問朋友們都明白,一個模型只有增刪改查的功能是不能滿足客戶實際需求的。在SAP Cloud for Customer裡,開發顧問可以在Cloud Application Studio裡建立beforeSave和afterModify這些指令碼檔案並實現業務邏輯,筆者也曾經介紹過,它們相當於S/4HANA BOPF框架裡建立的determination.
除了上述在執行時特定的時間點才能觸發(beforeSave,afterModify)的邏輯外,Action機制則提供了自由度更高的業務邏輯編寫機制。體現在UI上,Action邏輯一般通過UI按鈕觸發。
Validation比較容易理解——自定義的資料校驗邏輯。
本文按照順序介紹 RAP 的 Action和Validation.
為了介紹在Restful ABAP Programming模型下如何開發Action,我們在前一篇文章建立的SFLIGHT表增添一個表示航班預訂狀態的欄位,並開發一個Action,當其被呼叫時,修改這個狀態。
(1)在資料庫表裡增添一個OVERALL_STATUS欄位:
當然在對應的CDS view上也要通過 @UI
相關的註解把這個欄位配置到UI上。通過註解lineItem和identification分別把view的這個欄位顯示在搜尋結果的table控制元件和航班資訊明細頁面的欄位上。通過label指定UI上顯示的標籤,通過註解的dataAction把這個狀態欄位繫結到一個名為acceptTravel的Action上。
重新啟用CDS view後,我們就能在工具欄上看到CDS view裡通過label維護的標籤文字為Accept Travel了:
因為缺乏實現,此時點選無效果。
(2) 在Behavior Definition的宣告部分,新增如下三行程式碼:
action ( features: instance ) acceptTravel result [1] $self;
validation validateCustomer on save { field customer_id; }
validation validateDates on save { field begin_date, end_date;
上面的程式碼除了定義一個Action外,還聲明瞭兩個Validation,在特定欄位發生變化並儲存時觸發校驗邏輯,欄位名稱維護在大括號內。
剩下的就是ABAP程式設計實現了。在Behavior Definition的ABAP實現類裡,宣告下面這些ABAP類方法,來實現Behavior Definition裡的定義。
首先看Action的實現,位於ABAP方法SET_STATUS_COMPLETED裡:
將輸入引數travel_id指定的航班預訂記錄的狀態欄位置為A - Accepted.
現在我選中ID為22這條記錄,點選Accept Travel按鈕:
點選之後,狀態成功被置為A了:
再來加上對航班日期的校驗:如果航班結束日期在起始日期之前,顯然不合理,需要彈一條錯誤訊息。
第87行到第91行把輸入引數包含的航班資訊讀到內表lt_travel_result裡,然後第95行把結束日期和起始日期做比較,如果後者早於前者,進入97行開始的IF分支,彈一個錯誤資訊到UI.
錯誤資訊仍然和傳統的ABAP程式設計一樣,通過ABAP Message類定義:
現在把結束日期維護成起始日期之前,儲存的時候就看到了期望的錯誤訊息:
至此,我們這個SFLIGHT模型除了增刪改查之外,又增添了Action和Validation的功能。
應用開發完成後,我們就可以開始除錯了。
我選中ID為103這條記錄,點選Accept Travel按鈕後,期望通過該Action將其狀態設定為Accepted:
不幸的是,我沒能看到期望中的狀態變化,而是下面這個所有ABAP程式設計人員都不願意看見的ABAP執行時錯誤提示介面。
不過,大家注意到了上圖右下角的Debug超連結麼?和SAPGUI一樣,點選之後立即就能開啟偵錯程式,能夠觀察發生這個執行時錯誤的呼叫棧,引起錯誤的詳細程式碼位置和相關變數的值。
回到ABAP Development Tool裡,我們先點選Show超連結,就可以看到執行時錯誤明細:Short Text告訴我們,我們點選Accept按鈕後,相關的處理框架有意地丟擲一個CX_CSP_ACT_RESPONSE的異常。丟擲異常的位置是在程式CL_CSP_ACT_CHECK_FEATS_ACTIONS裡,這暗示我們,這個錯可能和Action執行前的檢查(CHECK)有關。
繼續向下滑動滑鼠,發現在框架程式碼內,因為從第353行內表it_feature_result裡沒有讀出任何內容,因此sy-subrc不為0,導致進入第355行的RAISE SHORTDUMP分支。
在SAP Cloud Platform ABAP環境下當前登入使用者發生的所有執行時錯誤,可以在ABAP Development Tool的Feed Reader檢視下檢視,這個功能相當於SAP GUI裡的ST22事務碼。
現在我們關於這個執行時錯誤的靜態資訊瞭解得差不多了,下一步在偵錯程式裡觀察。
重新啟動Fiori應用,再次點選Accept按鈕,出現執行時錯誤後點擊Debug超連結,ABAP偵錯程式自動彈出,引起執行時錯誤的那一行程式碼被高亮,同時左邊顯示出呼叫棧。
把滑鼠放在it_feature_result上,發現這個內表是空的,當然無法從裡面讀出資料了。這個內表是當前ABAP類CL_CSP_ACT_CHECK_FEATS_ACTIONS的方法handle_rejected_instances的輸入引數,需要搞清楚為啥這個輸入引數為空。
從丟擲執行時異常的棧幀往外看一幀,就知道這個輸入的內表是通過第291行的execute_feature_controllers生成的,這個方法會通過回撥函式的方式,呼叫我們在Behavior Definition實現的一個get_features方法裡:
這裡我們就找到了引起這個執行時錯誤的根源:因為之前筆者出於測試目的,註釋了一段程式碼,導致get_features被框架回調時,沒有返回框架期望的資料:
當Jerry把這段需要的程式碼重新enable然後設定斷點,點選Accept按鈕,通過呼叫棧可以清晰看到框架的execute_feature_controllers是如何呼叫到我們實現的get_features回撥方法的。
總結
本文首先在一個支援增刪改查四種基礎操作的 RAP 應用上,增添了 Action 和 Validation 實現,二者都是雲端 ABAP 程式設計環境裡進行業務邏輯編寫的重要手段。其次介紹了雲端 ABAP 程式設計環境中進行開發的必備技巧,即程式碼的單步除錯。