本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
AWS 藍光時代結構的現代化應用程序
本文件提供現代化應用程式結構的詳細資訊 (使用 AWS 大型主機現代化重構工具),讓開發人員能夠完成各種工作,例如:
-
流暢地導航到應用程序。
-
開發可以從現代化的應用程序被調用的自定義程序。
-
安全地重構現代化應用程式。
我們假設您已經掌握了以下內容的基本知識:
-
舊式通用編碼概念,例如記錄、資料集及其存取模式,以記錄索引、順序-VSAM、執行單元、jcl 指令碼、CICS概念等。
-
java 編碼使用春天框架
。 -
在整個文檔中,我們使
short class names
用可讀性。如需詳細資訊,請參AWS 藍色時代完整名稱對應閱擷取 AWS Blu Age 執行階段元素的對應完整名稱,第三方完整名稱對應以及擷取協力廠商元素的對應完整名稱。 -
所有成品和樣本都是從樣本COBOL/CICSCardDemo 應用
程序的現代化過程輸出中獲取的。
成品組織
AWS 藍光時代現代化的應用程式會封裝成 Java Web 應用程式 (.war),您可以在伺服器上部署。JEE通常情況下,服務器是一個嵌入 AWS 藍光時代運行時的 Tomcat
戰爭聚合了幾個組件工件(.jar)。每個 jar 都是專用 java 項目的編譯(使用 maven
基本組織依賴於以下結構:
-
實體項目:包含業務模型和上下文元素。項目名稱通常以「-實體」結尾。通常,對於給定的舊版COBOL程序,這對應於 I/O 部分(數據集)和數據分割的現代化。您可以有多個實體專案。
-
服務專案:包含傳統的商務邏輯現代化元素。通常情況下,程序的過程COBOL劃分。您可以擁有多個服務專案。
-
實用程序項目:包含共享的常用工具和實用程序,由其他項目使用。
-
Web 項目:包含 UI 相關元素的現代化(如果適用)。不適用於僅批次現代化專案。這些 UI 元素可能來自CICSBMS地圖、IMSMFS元件和其他大型主機 UI 來源。您可以有一個以上的 Web 專案。
實體專案內容
注意
以下說明僅適用於COBOL和 PL/I 現代化輸出。RPG現代化輸出以不同的配置為基礎。
在進行任何重構之前,實體專案中的封裝組織會繫結至現代化方案。您可以通過幾種不同的方式完成此操作。首選的方法是使用重構工具箱,該工具箱在觸發代碼生成機制之前運行。這是一個高級操作,這在 BluAge 培訓中進行了說明。如需詳細資訊,請參閱重構研討
課程相關課程
每個現代化程序都與兩個軟件包相關,一個業務 .context 和一個商業 .model 軟件包。
-
base package
.program
.business.context該業務 .context 子包包含兩個類,一個配置類和一個上下文類。
-
程式的一個組態類別,其中包含指定程式的特定組態詳細資訊,例如用來表示以字元為基礎的資料元素的字元集、填補資料結構元素的預設位元組值等等。類名以「配置」結尾。它用
@org.springframework.context.annotation.Configuration
註釋標記,並包含必須返回正確設置Configuration
對象的單個方法。 -
一個上下文類,它作為程序服務類(見下文)和數據結構()和數據集(
Record
)從模型子包(File
)之間的橋樑(見下文)。類名以「上下文」結尾,是該類的一個子RuntimeContext
類。
-
-
base package
.program
.business.model該模型子包包含所有給定的程序可以使用的數據結構。例如,任何 01 級COBOL數據結構對應於模型子包中的一個類(較低級別的數據結構是其擁有 01 級結構的屬性)。有關我們如何現代化 01 數據結構的更多信息,請參閱AWS 藍光時代的數據簡化器是什麼。
所有類擴展RecordEntity
類,它代表對業務記錄表示的訪問。一些記錄有一個特殊的目的,因為它們綁定到File
. a Record
和 a 之間的綁定File
是在創建文件對象時在上下文類中找到的相應 * FileHandler 方法中進行的。例如,下列清單顯示 TransactfileFile File
如何繫結至 transactFile Record
(從模型子套件)。
服務項目內容
每個服務項目都配備了一個專用的 SpringbootSpringBootLauncher
的類來實現:
這個課程特別負責:
-
在程序類和託管資源(數據源/事務管理器/數據集映射/等)之間製作膠水。
-
提供一
ConfigurableApplicationContext
個程序。 -
發現標記為彈簧組件(
@Component
)的所有類。 -
確保程序正確註冊在
ProgramRegistry
--請參閱負責此註冊的初始化方法。
程式相關加工品
在沒有事先重構的情況下,業務邏輯現代化輸出會根據每個舊版程式的兩個或三個套件進行組織:
最詳盡的案例將有三個包:
-
base package.program.service
:包含一個名為 Program Pro cess 的介面,該介面具有用於處理業務邏輯的業務方法,並保留傳統執行控制流程。 -
base package.program.service.impl
: 包含一個名為 Program 的類ProcessImpl,這是前面描述的 Process 接口的實現。這是遺留語句被「翻譯」為 java 語句的地方,依賴於 AWS Blu Age 框架: -
base package.program.statemachine
:這個軟件包可能並不總是存在。當傳統控制流程的現代化必須使用狀態機器方法(即使用 S pring StateMachine 框架)來正確覆蓋傳統執行流程時,這是必需的。 在這種情況下,靜態子包包含兩個類:
-
ProgramProcedureDivisionStateMachineController
: 擴充用於驅動 Spring 狀態機力學的類別StateMachineController
(定義控制狀態機執行所需的作業) 和StateMachineRunner
(定義執行狀態機所需的作業) 介面的類別;例如,SimpleStateMachineController
如範例中所示。狀態機控制器定義了可能的不同狀態和它們之間的轉換,從而重現給定程序的傳統執行控制流程。
在構建狀態機時,控制器指的是在位於狀態機包中的相關服務類中定義的方法,如下所述:
subConfigurer.state(States._0000_MAIN, buildAction(() -> {stateProcess._0000Main(lctx, ctrl);}), null); subConfigurer.state(States.ABEND_ROUTINE, buildAction(() -> {stateProcess.abendRoutine(lctx, ctrl);}), null);
-
ProgramProcedureDivisionStateMachineService
: 此服務類別代表一些需要與狀態機控制器建立之狀態機器繫結的業務邏輯,如前所述。在這個類的方法的代碼使用狀態機控制器中定義的事件:
靜態服務也會呼叫先前描述的程序服務實作:
-
除此之外,一個名為的軟件包base package.program
起著重要作用,因為它每個程序收集一個類,這將作為程序進入點(稍後有關此更多詳細信息)。每個類實現接Program
口,標記為程序入口點。
其他文物
-
BMSMAPs同伴
除了方案相關的人工因素之外,服務專案還可以包含用於各種目的的的其他成品。在CICS線上應用程式的現代化情況下,現代化程序會產生一個 json 檔案,並放入 /src/main/resources 資料夾的地圖資料夾中:
Blu Age 運行時消耗這些 json 文件,以將SENDMAP語句使用的記錄與屏幕字段綁定。
-
常規的腳本
如果傳統應用程序有JCL腳本,那麼這些腳本已經被現代化為 groovy
腳本,存儲在 /src/main/資源/腳本文件夾中(稍後有關該特定位置的更多信息): 這些指令碼可用來啟動批次工作 (專用、非互動式、CPU 密集型資料處理工作負載)。
-
SQL文件
如果舊版應用程式使用SQL查詢,則相應的現代化SQL查詢已收集到專用屬性檔案中,並使用命名模式程式 .sql,其中的程式是使用這些查詢的程式名稱。
這些 sql 文件的內容是(key=query)條目的集合,其中每個查詢都與一個唯一密鑰相關聯,現代化程序用於運行給定的查詢:
例如,COSGN00C 程序正在使用密鑰「COSGN00C_1」(sql 文件中的第一個條目)執行查詢:
公用程式專案內
公用事業項目,其名稱以「-tools」結尾,包含一組技術實用程序,可能被所有其他項目使用。
Web 專案內容
Web 項目只有在現代化傳統 UI 元素時才存在。用於構建現代化的應用程序前端的現代 UI 元素基於 Angular
Web 專案只負責應用程式的前端方面依賴公用程式和實體專案的服務專案提供後端服務。前端和後端之間的鏈接是通過名為 Gapwalk-應用程序,這是標準的 AWS 藍光時代運行時分佈的一部分的 Web 應用程序進行。
運行和調用程序
在傳統系統上,程式會編譯為獨立的可執行檔,可透過CALL機制 (例如COBOLCALL陳述式) 自行呼叫,並在需要時傳遞引數。現代化的應用程式提供相同的功能,但使用不同的方法,因為所涉及的成品的性質與舊版的性質不同。
在現代化方面,程序入口點是實現Program
接口的特定類,是 Spring 組件(@Component),並且位於服務項目中,名為base package.program
。
程序註冊
每次託管現代化應用程序的 TomcatProgramRegistry
為專用的註冊表填充了程序條目,每個程序正在使用它的標識符,每個已知的程序標識符一個條目,這意味著,如果一個程序是由幾個不同的標識符已知,註冊表包含盡可能多的條目,因為有標識符。
給定程序的註冊依賴於由 getProgramIdentifiers()方法返回的標識符的集合:
在這個例子中,該程序被註冊一次,名為 'CBACT04C'(看看 programIdentifiers 集合的內容)。tomcat 日誌顯示每個程序註冊。程序註冊僅取決於聲明的程序標識符,而不是程序類名本身(儘管通常程序標識符和程序類名稱是對齊的。
相同的註冊機制適用於各種實用程序 AWS Blu Age Web 應用程序帶來的實用程序,這些應用程序是 AWS Blu Age 運行時分佈的一部分。例如,Gapwalk-Utiliy-Pgm web 應用程式提供 z/OS 系統公用程式 (IDCAMS、、等等) 的功能對等項目,ICEGENER而且可以透過現代化的程式或指令碼來呼叫。SORT在 Tomcat 啟動時註冊的所有可用公用程式都會記錄在 Tomcat 記錄檔中。
腳本和守護進程註冊
類似的註冊過程,在 Tomcat 啟動時,發生在/src /主/資源/腳本文件夾層次結構的groovy 腳本。腳本文件夾層次結構被遍歷,並且發現的所有 groovy 腳本(除了特殊的 functions.groovy 保留腳本)都在中註冊ScriptRegistry
,並使用它們的短名稱(腳本文件名的一部分位於第一個點字符之前)作為檢索的關鍵字。
注意
-
如果有多個腳本具有將導致產生相同註冊密鑰的文件名,則只會註冊最新的腳本,覆蓋任何先前遇到的該給定密鑰的註冊。
-
考慮到上述注意事項,使用子文件夾時請注意,因為註冊機制會扁平化層次結構並可能導致意外的覆蓋。層次結構在註冊過程中不計算:典型地/腳本/A /MyScript.Groovy 和/腳本 /B/MyScript.Groovy 將導致/腳本//MySCRIPT。
/src/主/資源/守程文件夾中的groovy 腳本的處理方式有點不同。它們仍然註冊為常規腳本,但此外,它們會直接在 Tomcat 啟動時間以異步方式啟動一次。
在中註冊指令碼之後ScriptRegistry
,REST呼叫可以使用 Gapwalk 應用程式公開的專用端點來啟動它們。如需詳細資訊,請參閱對應的文件。
程序調用程序
每個程序可以調用另一個程序作為一個子程序,傳遞參數給它。程序使用接ExecutionController
口的實現來這樣做(大多數情況下,這將是一個實ExecutionControllerImpl
例),以及一個名為 the 的流暢API機制CallBuilder
來構建程序調用參數。
所有程序方法都採用 a RuntimeContext
和 a ExecutionController
as 方法參數,因此始終可用於調用其他程序。ExecutionController
例如,請參閱下面的圖表,其中顯示 03 CBST A 程序如何調用 CBST 03B 程序作為子程序,並將參數傳遞給它:
-
的第一個引數
ExecutionController.callSubProgram
是要調用的程序的標識符(即用於程序註冊的標識符之一--見上面的段落)。 -
第二個引數,這是構建的結果
CallBuilder
,是一個數組Record
,對應於從調用者傳遞給被調用者的數據。 -
第三個也是最後一個引數是呼叫者
RuntimeContext
實例。
所有這三個參數都是強制性的,不能為 null,但第二個參數可以是一個空數組。
被調用者將能夠處理傳遞的參數,只有當它最初被設計為這樣做。對於傳統程COBOL序,這意味著具有一個LINKAGE部分和一個USING子句,用於程序劃分以利用這些LINKAGE元素。
例如,請參閱相應的 CBSTM03B。 CBL
所以 CBSTM 03B 程序將一個單個Record
作為參數(大小為 1 的數組)。這是使用byReference()和getArguments()方法鏈接的構建。CallBuilder
CallBuilder
流利的API類有幾種方法可用於填充參數數組以傳遞給被調用者:
-
asPointer(RecordAdaptable):通過引用添加指針類型的參數。指針表示目標數據結構的地址。
-
byReference(RecordAdaptable):通過引用添加參數。呼叫者將看到被呼叫者執行的修改。
-
byReference(RecordAdaptable):以前方法的可變參數變體。
-
byValue(對象):添加一個參數
Record
,按值轉換為 a。呼叫者不會看到被呼叫者執行的修改。 -
byValue(RecordAdaptable):與前面的方法相同,但參數直接作為
RecordAdaptable
. -
byValueWith邊界(Object,int,int):添加一個參數,轉換為 a
Record
,按值提取由給定邊界定義的字節數組部分。
最後,該 getArguments 方法將收集所有添加的參數並將其作為數組返回Record
。
注意
確保 arguments 數組具有所需的大小,就內存佈局與鏈接元素的預期佈局而言,這些項目是正確排序和兼容的調用者的響應性。
腳本調用程序
從 groovy 腳本調用註冊的程序需要使用實現MainProgramRunner
接口的類實例。通常,獲得這樣的實例是通過 Spring 的 ApplicationContext 使用來實現的:
MainProgramRunner
接口可用後,使用該 runProgram 方法調用程序並將目標程序的標識符作為參數傳遞:
在前面的範例中,作業步驟呼叫 IDCAMS (檔案處理公用程式),提供實際資料集定義及其邏輯識別碼之間的對應。
在處理數據集時,舊版程序大多使用邏輯名稱來識別數據集。從指令碼呼叫程式時,指令碼必須將邏輯名稱與實際的實體資料集對應。這些數據集可以位於文件系統中,在 Blusam 存儲中,甚至由內聯流,多個數據集的串聯或. GDG
使用此方 withFileConfiguration 法建立資料集的邏輯對實體對應,並將其提供給被呼叫的程式。
編寫您自己的程序
為腳本或其他現代化程序編寫自己的程序來調用是一項常見任務。一般而言,在現代化專案中,當可執行的舊版程式是以現代化程序不支援的語言撰寫,或是來源已遺失 (是的,可能發生這種情況),或程式是無法取得來源的公用程式時,撰寫自己的程式。
在這種情況下,您可能必須自己用 java 編寫丟失的程序(假設您對程序預期行為應該是什麼有足夠的了解,程序參數的內存佈局(如果有的話)。您的 java 程式必須符合本文件中描述的程式機制,以便其他程式和指令碼可以執行它。
若要確保程式可用,您必須完成兩個強制步驟:
-
編寫一個正確實現接
Program
口的類,以便它可以被註冊和調用。 -
確保您的程序已正確註冊,以便從其他程序/腳本中可見。
編寫程序實施
使用您IDE的創建一個實現Program
接口的新 Java 類:
下圖顯示了 EclipseIDE,它需要創建要實現的所有強制性方法的護理:
彈簧整合
首先,類必須聲明為 Spring 組件。用@Component
註釋註釋類:
接下來,正確實施所需的方法。在此範例的內容中,我們將新增MyUtilityProgram
至已包含所有現代化程式的套件中。該放置允許程序使用現有的 Springboot 應用程序來提供所需ConfigurableApplicationContext
的 getSpringApplication 方法實現:
您可以為自己的程序選擇不同的位置。例如,您可以在另一個專用服務項目中找到給定的程序。確保給定的服務項目有自己的 Springboot 應用程序,這使得它可以檢索 ApplicationContext (應該是一個ConfigurableApplicationContext
)。
給一個身份的程序
要被其他程序和腳本調用,該程序必須給予至少一個標識符,這不能與系統中的任何其他現有的註冊程序發生衝突。識別碼的選擇可能是由於需要涵蓋現有舊版程式替換的需求所驅動;在這種情況下,您必須使用預期的識別碼,如同在整個舊版程式中發現的CALL事件中所遇到的那樣。在傳統系統中,大多數程序標識符都是 8 個字符。
在程序中創建一組不可修改的標識符是執行此操作的一種方法。下列範例顯示選擇 "MYUTILPG" 作為單一識別碼:
將方案與前後關聯產生關聯
該程序需要一個伴隨RuntimeContext
實例。對於現代化程序, AWS Blu Age 使用屬於舊計劃一部分的數據結構自動生成伴隨上下文。
如果您正在編寫自己的程序,則還必須編寫伴隨上下文。
參考一下課程相關課程,您可以看到一個程序至少需要兩個同伴課程:
-
一個配置類。
-
使用配置的上下文類。
如果實用程序使用任何額外的數據結構,它應該被寫入,以及由上下文使用。
這些類應該在一個包中,該軟件包層次結構的一部分將在應用程序啟動時進行掃描,以確保上下文組件和配置將由 Spring 框架處理。
讓我們在實體項目中新創建的base package.myutilityprogram.business.context
包中編寫一個最小的配置和上下文:
以下是配置內容。它使用的配置構建類似於附近的其他現代化程序。您可能必須根據您的特定需求進行自定義。
備註:
-
一般命名慣例為「ProgramName組態」。
-
它必須使用 @org. 彈簧框架. 上下文. 註釋. @Lazy
-
bean 名稱通常遵循ProgramNameContextConfiguration 慣例,但這不是強制性的。確保避免整個項目中的 bean 名稱衝突。
-
要實現的單個方法必須返回一個
Configuration
對象。使用ConfigurationBuilder
流利API來幫助您構建一個。
和相關的上下文:
備註
-
上下文類應該擴展現有的
Context
接口實現(RuntimeContext
或者JicsRuntimeContext
,這是一個JICS具RuntimeContext
有特定項目的增強)。 -
一般命名慣例是ProgramName上下文。
-
您必須將其宣告為原型元件,並使用 @Lazy 註解。
-
構造函數引用相關的配置,使用 @Qualifier 註釋來定位適當的配置類。
-
如果實用程序使用一些額外的數據結構,它們應該是:
-
寫入並添加到
base package.business.model
包中。 -
在上下文中引用。看看其他現有的上下文類,看看如何引用數據串類,並根據需要調整上下文方法(構造函數/清理/重置)。
-
現在有專用上下文可用,讓新程序使用它:
備註:
-
該 getContext 方法必須嚴格執行,如圖所示,使用對
ProgramContextStore
類的 getOrCreate 方法和 auto 有線 Spring 的委託BeanFactory
。單個程序標識符用於存儲在程序上下文ProgramContextStore
; 這個標識符被引用為「程序主標識符」。 -
伴隨配置和上下文類必須使用
@Import
spring 註釋引用。
實作業務邏輯
當程式架構完成時,請實行新公用程式的企業邏輯。
在程序的run
方法中執行此操作。此方法將在任何時候程序被調用,無論是由另一個程序或由腳本執行。
快樂的編碼!
處理程序註冊
最後,請確定新程式已在中正確註冊ProgramRegistry
。如果您將新程序添加到已包含其他程序的軟件包中,則無需執行任何操作。在應用程序啟動時,將新程序拾取並註冊其所有鄰居程序。
如果您為程序選擇了其他位置,則必須確保該程序在 Tomcat 啟動時正確註冊。有關如何執行此操作的一些靈感,請查看服務項目中生成的 SpringbootLauncher 類的初始化方法(請參閱服務項目內容)。
檢查 Tomcat 的啟動日誌。每個程序註冊都會記錄下來。如果您的程序已成功註冊,您將找到匹配的日誌條目。
當您確定您的程序已正確註冊時,可以開始迭代業務邏輯編碼。
完整名稱對映
本節包含 AWS Blu Age 和第三方完整名稱對應的清單,可用於現代化的應用程式。
AWS 藍色時代完整名稱對應
短名稱 | 完整名稱 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
第三方完整名稱對應
短名稱 | 完整名稱 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|