程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 使用Spring的Web服務模擬器框架解決方案

使用Spring的Web服務模擬器框架解決方案

編輯:關於JAVA

大型 Web 開發計劃通常會由多個開發項目組成,這些項目由分布在不同地域的團隊全天候同步進行。 由這些團隊開發的各個組件需要盡可能實現無縫互操作。這類開發的關鍵要求是在負責構造不同組件的團 隊之間建立好約定。一個好的模擬器框架通過實現各個接口約定所支持的全部請求和響應來保證盡可能的 團隊獨立性,並潛在地提高生產率。本文將描述在快速 Web 開發環境中使用模擬器框架,逐步演示如何 使用 Rational® Application Developer 快速創建一個模擬器框架,並包含了一些示例與代碼。

簡介

復雜的開發項目往往要求各個階段的開發流程盡可能相互獨立。假設流程之間的接口 (不同子系統間的約定)已經在軟件開發生命周期(SDLC)中盡可能地提前完成,一個好的基於模擬器的 開發策略能在開發過程中實現顯著的優化。

這點對於將新應用程序和系統部署到現有環境期間尤其重要,比如在電信領域,該領域混合了大量的 Independent Software Vendor (ISV),並且非功能性需求相當重要,尤其是管理系統延遲和吞吐量方面 。在這些復雜環境中,許多因素使得在現有環境中實際交付新應用程序變得很復雜。其中一些因素包括:

需要開發和發布某些功能,但是缺乏新的應用程序所依賴的所有系統和服務

需要最大程度 地同時進行與不同流程相關的開發活動,同時又要盡量減小流程之間的相互依賴

需要在發布功能 時證明新應用程序能夠滿足端到端的吞吐量和延遲需求

需要使開發團隊避免對子系統進行修改, 他們需要在 SDLC 的編碼和單元測試階段依賴這些子系統

需要在一個可重復、穩定、可靠的流程 內輕松地提供各種測試數據場景

在所有這些領域中,一個功能健壯的模擬器框架將會很有價值。 本文將描述這樣一個模擬器框架,並解釋如何使用 WebSphere® Application Server 來構造一個模 擬器框架。此處將重點講解一個使用 Service Oriented Architecture (SOA) 的應用程序,可將此擴展 到其他類型的環境和架構中。

模擬器最佳實踐

模擬器概覽

韋氏詞典對模擬器的定 義是 “能在試驗條件下重現或表示出有可能會在真實情況中發生的現象的設備 ”。模擬器可 在 SDLC 過程中使用,通過為後台服務提供端點實現更加敏捷的開發環境,後端服務呈現為一個調用應用 程序,但實際上只是模擬真實的系統。模擬器以與實時後台服務相同的形式進行響應,並使用相同的請求 /響應約定,但只是簡單地從配置數據返回預置數據。這樣就可以對支持系統的功能性和非功能性特性建 模,即使您沒有訪問系統本身。

比較常見的和通用的編程實踐是使用 stub 接口,這種接口繞過 了本地客戶端接口調用,而是執行另外的本地代碼路徑並返回預置數據。很多情況下,stub 可加速初始 開發,但無法實現執行整個代碼路徑和調用工作接口所能獲得的功能。使用 stub 方法時,應用程序需要 知道它正處在 “stub 模式” 下,這樣才可以執行不同的代碼路徑。通過使用模擬器,應用 程序只改變端點,而不會知道響應來自於模擬的後台系統。

圖 1 和圖 2 顯示出兩種方法的區別

圖 1. 應用程序使用本地 stub 代碼,繞過 Web 服務調 用

圖 2. 應用程序 使用模擬器作為 Web 服務端點,取代活動的後台系統

大多數情況下,應用程 序會與各種 Web 服務交互,您可能最初希望在活動接口不可用時使用 stub 方法。這會在用戶接口快速 生成所需的可視流程,但客戶端的 stub 不會測試數據的內部連接與編組。因此,模擬越深入,獲益越大 ,因為可以運行更多的系統功能。圖 2 演示了創建模擬器的最佳位置。

為了更深入地演示這個概 念,讓我們查看一個 Web 2.0 示例,它包含一個來自客戶端的 Asynchronous JavaScript and XML (Ajax) 請求和一個來自服務器的 JavaScript Object Notation (JSON) 響應,該服務器依賴後台系統構 建響應。

圖 3. Web 2.0 交互示例

建立的第一個約定是客戶端與應用程序間的 JSON 對象。第二個約定位於應用程序與使用 Web Service Definition Language (WSDL) 的後台服務器之間。在初始開發階段,JSON 約定和 Web Service 約定表示的是可以創建 stub 接口的共同位置點,這樣就可通過維護約定來保持不同開發人員的獨立性。

理論上,當每個開發小組按照約定完成開發任務後,就可以順利地集成應用程序。然而,在實際 中,當集成多個外部系統時,情況並非如此。在接口集成期間經常會返回意外結果,或者服務到服務之間 出現一系列依賴調用,這需要對調用進行編排。一個被破壞的或不可用的接口可能阻塞多個下游開發團隊 。

在開發中使用模擬器的優點

當與多個團隊開發復雜系統(存在許多依賴關系)時,幾乎 不可避免地會出現接口延遲的風險。服務模擬將會成為重要的風險緩解工具,可以在開發復雜系統時采用 該工具來顯著減少風險與延遲。

在決定模擬程度時需要考慮幾個關鍵因素。很多情況下,最簡單 的模擬是不管輸入是什麼都返回相同的響應。這對於初始單元測試有效,但很難保證獲得優質的代碼。更 常見的做法是,對模擬器加以擴展,能夠根據請求數據返回更復雜的響應。某些情況下,用請求數據在 XML 文件中查找響應。對於其他的情況,在計算中重用或處理請求數據以用於響應。

為了能實現 更復雜的響應,需要構建簡單、靈活和輕量級的模擬器模式,以便能被開發人員輕松采用,並且還提供了 深入的模擬。

圖 4. 模擬器可訪問的數據將影響其對於開發團隊的可用性以及最後的成功

使用模擬器進行功能測試的優點

在 SLDC 中使用模擬的好處超越了開發階段。更新的技術,如 scrum、極限編程、特征驅動開發,可以促進迭代開發,但可能與傳統的瀑布驅動方法沖突,在瀑布驅動 方法中,一些連續的接口(gate)需要匯合以移到下一階段。如果快速開發組件依賴於關鍵接口且開發周 期較長,迭代測試就難以實現。在這種情況下,模擬器將會在活動接口可用前測試組件,並能提前發現主 要問題。當試圖向後台系統提供測試數據以支持可能發生的錯誤場景時,通常會遇到挑戰。模擬器會提供 有效的替代方法測試不常見的場景或難以使用活動後台系統實現的反向(negative)測試案例。

模擬器也提供了一個強大的風險緩解策略。隨著系統接口數量和復雜性的增加,故障和延期的風險也會增 加。以下的情況經常會出現:接口不可用,因為需要使用補丁修復錯誤;或者開發人員必須安排宕機時間 來處理活動測試窗口中的接口。這種情況下,開發和測試團隊需要付出更多寶貴的時間才能實現一個完整 的、有效的系統。通過在測試環境中使用模擬器,應用程序可以為特定的接口重新配置接口端點,將其從 不可用的服務調整到正常的模擬服務,從而避免出現停機。測試系統可以繼續對所有工作中的系統使用活 動接口,只對不可用的服務使用模擬器。

通常會開發一個服務指示板來結合用於模擬器,從而支 持開發人員與測試人員測試模擬服務的請求和響應。這可以對請求數據配置進行快速驗證。由於模擬器模 仿活動的後台服務,服務指示板也可以在活動後台服務可用時測試和解決故障。某些情況下,服務指示板 會揭示出一些在模擬器中不可用的獨特響應場景。服務指示板可包含記錄原始請求和響應的功能,能夠擴 展模擬器以使其將該場景添加到模擬集中。

圖 5 演示了由一組後台服務和模擬器共同支持的系統 的邏輯視圖。圖中顯示了一個外部應用程序通過 Enterprise Service Bus (ESB) 連接到各個服務。黃顏 色的服務(服務 1、2 和 7)指示服務此刻不可用,由模擬器提供。紅顏色服務(服務 3 和 4)表示服 務正在部署或是不可用。指向紅顏色服務的請求將通過 ESB 重新路由到模擬服務上。

圖 5. 同時 利用模擬服務和活動後台服務的系統的邏輯視圖

使用模擬器進行非功 能性測試的優點

性能測試是 SDLC 中的重要方面。許多情況下,用於測試的環境無法模擬出生產 環境的性能特點。經常有這樣的情況,公司的系統由於過於昂貴而無法在測試環境中完全重現。這種情況 下,模擬器可以很好地支持性能測試,因為它們能模擬出期望的生產環境。

要理解為什麼模擬器 會成為很好的性能測試工具,需要對負載有所理解。Little 的 負載定律(Law of Load)指出,平均負 載(L)等於到達率(λ)乘以完成事務的平均處理時間(T)。即,L = λT。

如果 一個應用程序需要 1 秒的時間來響應請求,那麼每秒的請求數必須是 1,負載才能均衡。圖 6 演示的是 到達率上升而持續時間不變的情況。許多前端負載測試工具強調提高到達率以產生負載。

圖 6. 增加每秒請求數而響應時間不變

反過來也一樣,並且 展示了到達率在注冊時未改變,但應用程序的響應時間會降低。圖 7 顯示的是響應率下降而請求率不變 的情況。

圖 7. 每秒請求數不變,響應時間下降

圖 6 和圖 7 在復雜 系統中都很常見。值得注意的是請求率和響應時間都對負載有顯著影響。

負載測試通常會強調通 過增加客戶端訪問應用程序的到達率增加負載(λ)。這通常可由 Mercury Load Runner 或 IBM Rational Performance Tester 之類的負載生成工具實現,但沒有處理後台系統用於返回結果的預期平均 處理時間(T)。作為推薦的最佳實踐,模擬器可以和性能模型聯合使用以生成更貼近生產環境的性能測 試,通過使用性能模型決定每個接口的平均響應,並將這些響應時間編入到模擬器中。

可根據生 產中現有的或預期的響應時間,用性能模型文檔記錄每個生產系統的 Service Level Agreements(SLA)。 這包括不同級別的請求率的響應時間。通常,每個請求的響應時間將會隨著每秒事務量 (TPS) 的增加而 減少。這些變化的響應時間也會被包含到模擬器內,以更好地對預期生產環境建模。

通過在服務 中模擬暫時的 “hiccup” 或暫停,或者通過模擬預計的 SLA 以外的響應來衡量對依賴系統 的影響,模擬器還可以用於實現反向性能測試場景。這種額外的測試級別允許在 SDLC 中盡早發現並解決 問題。

技術實現概覽

以下內容將介紹模擬器框架的具體實現。它利用 Spring 2.0 Framework 將以 XML 格式存儲的響應數據轉換成 Plain Old Java Objects (POJO),以用來表示相關的 服務響應。該框架支持使用模擬器和指示板進行單元測試。模擬器框架包含以下幾個已定義的層:

Web 服務

模擬器解決方案的底層框架包括 Web 客戶端和 Web 服務。主應用程序內部運行的 Web 客戶端和模擬器的接收 Web 服務都是根據所提供的 WSDL 生成的。WSDL 允許自動生成測試業務功能 所必需的請求和響應對象。

指示板層

指示板層含有用戶接口組件,用來收集數據供客戶端 服務層生成請求對象。在收集數據時,指示板同樣會顯示與被調用的模擬器服務相關的結果。指示板也可 在測試真實 Web 服務時用作健康檢查工具來驗證連通性和結果。

客戶端服務層

客戶端服 務層定義了具體的實現類,負責從指示板傳遞數據、生成請求對象和調用特定的模擬器服務。

模 擬器服務層

模擬器服務層負責生成請求對象,該對象會返回到進行調用的客戶端服務。該層從請 求中提取關鍵值,請求將會傳遞到處理層,後者用於檢索 XML 文件中相關的測試數據。在處理層中,將 會在返回響應前應用生成正確響應所必需的全部業務邏輯。

處理層

處理層將會使用模擬器 服務提供的鍵值來確定需要檢索的 Spring XML 文件。檢索完成後,Spring BeanFactory 將會使用該 XML 文件並將數據轉換成已定義的 POJO,後者將被返回給模擬器服務層。處理層的另一個作用是引入處 理延遲,這樣可以模擬不同類型的事務延遲。

數據層

數據層是 XML 文件的儲存庫,這些 文件用來表示 Web 服務響應對象。這些 XML 文件定義了簡單、一致的方法來生成 JavaBean 對象,這些 對象可由符合 spring-beans-2.0.dtd 標准的 Spring BeanFactory 管理。對 XML 文件的檢索由 Spring File System Resource 處理,並使用 Spring XmlBeanFactory 類將 XML 文件轉換為已定義的 POJO。

WebSphere 資源提供者

WebSphere 資源提供者被用作一個存儲解決方案,用於維護模擬器 解決方案中使用的動態配置值。可使用管理控制台添加、修改、部署值,從而可以在單獨或集群環境中實 現輕松的維護。

圖 8. 模擬器框架圖解

技術實現步驟

以下是一個創建模擬器應用程序示例的詳細步驟:

從提供的 WSDL 中生 成 Web 服務工件。

生成指示板 UI 組件以捕獲輸入。

在 RPC 配置中映射服務的實現、方 法、輸入參數。

生成客戶端實現以收集請求對象並將其傳遞給模擬器服務。

生成模擬器服 務,將業務規則運用到生成的響應對象上。

生成 Spring XML 數據文件,此文件將會被轉換成響 應對象。

配置 WebSphere Environment Provider 值以支持應用程序。

Web 客戶端和服務

Web 服務是模擬器框架的基礎。此前已定義的 WSDL 用來生成 Web 服務工件,將在 Web 服務工 件之上進行構建來提供執行模擬器業務用例所需的功能。用客戶端實現這些內容後,就創建了最基本的 WSDL 和基於 WSDL 的 Web 服務客戶端。以下步驟將指導您根據一個 WDSL 示例生成 Web 服務。

使用 Rational Application Developer (RAD) 平台,通過向導工具快速生成 Web 服務和客戶端。

Web 服務創建

在 RAD 內,創建一個包含 Web 服務和模擬器支持工件的新 Web 項目。

圖 9. 創建動態 Web 項目

在項目的 “src” 樹下添加 “wsdl” 文件夾。添加表示要模擬的 Web 服務的 WSDL。添加 WSDL 中提供的相關的 namespace-to-package 屬性文件以用於生成服務和客戶端。

圖 10. 支持資源 文件

右鍵單擊 WSDL 並選 擇 Web Services > Generate Java bean skeleton,創建 Web Service。將打開 Web Service Wizard。

圖 11. 創建 Java bean 骨架

確認 Web Service 向導設置。通常使用默認值。

圖 12. 驗證 Server、Service Project 和 EAR

選擇 將名稱空間映射到包的選項,這在生成的對象中提供了一種更友好的包結構。

圖 13. 驗證源文件夾並 選擇自定義映射

單擊 Import 導入名 稱空間和包,然後單擊 Finish。

圖 14. 將名稱空間導入到包定義中

單擊 Finish 後,Web 服務的客戶端和服務端所需的對象就生成了。新的對象將會顯示在選中包名下創建的項 目中。

模擬器指示板

模擬器指示板提供用於測試模擬器服務的 UI 組件。對於要進行測試 的每個 Web 服務,將會創建一個 JSP 來捕獲在客戶端服務層內生成 SOAP 請求對象所需的所有數據。

指示板層利用了一些工具,這些工具提供了快速的開箱即用功能,可以幫助在模擬器解決方案中 收集、檢索和顯示數據。將使用兩個部分組成指示板:

Ajax — 用 Ajax 組件來收集信息、 與服務層通信、呈現響應數據。

IBM Web 2.0 Feature Pack – RPC Adapter Servlet —RPC Adapter Servlet 將 Ajax 請求映射到所需的服務實現和管理 Http 請求及其內部數據的方法。生成的 bean 將由 RPC Adapter Servlet 轉換成 JSON 對象,該對象以後可使用 Ajax 在 JSP 中呈現。

圖 15. RPC Adapter 與 Web 客戶端調用流的 JSP 之間的關系

特定於模擬器的 JSP

JSP 將定義客戶端服務實現所需的輸入,以形成傳遞給模擬 器的請求對象。在捕獲所需的輸入值的同時,JSP 將用 callback 函數與 RPC Adapter 配置中定義好的 指定實現進行交互。模擬器返回的數據將通過 RPC Adapter servlet 轉換成 JSON 對象並在其中顯示。

JSP 包含以下內容:

從 WebSphere Resource Provider 中檢索默認的模擬器端點 (WebSphere Resource Environment Provider 中有關於 Resource Provider 配置的討論)。

<% String acctEndPoint=(String)EnvironmentProviderUtility
        .getWebServiceEnvironmentAttribute
       ("AccountSearch.Endpoint"); % >

定義客戶端服務所需的所有 HTML 輸入字段以生成 SOAP 請求。

創建 Ajax 回調函數,這些回調函數被映射到所需的處理服務實現和方法。

getRpcDataAccountSearch  ('AccountSearchImpl','getAccountsBy
       Equipment',  $('accountEndPoint').value,
         $('equipId').value,'getAccountsByEquipment')

圖 16. 簡單的指示板 JSP

RPC Adapter servlet 配置

RPC Adapter Servlet 必須在模擬器項目中使用 IBM Web 2.0 Feature Pack 提供的文件按照以下步驟配置:

IBM Web 2.0 Feature Pack – RPC Adapter Servlet— 通過編輯 web.xml 文件並添加 RPX Adapter Servlet 定義,在模擬器項目中 注冊 IBM WEB 2.0 Feature Pack – RPC Adapter Servlet。清單 1 顯示的是在 web.xml 文件中 注冊 BM RPC Adapter servlet。

清單 1. 向 web.xml 文件添加 RPC Adapter Servlet 定義

<servlet>
  <description> IBM WEB 2.0 Feature Pack -  RPC Adapter </description>
  <display-name>RPCAdapter</display- name>
  <servlet-name>RPCAdapter</servlet-name>
  <servlet- class>com.ibm.websphere.rpcadapter.RPCAdapter</servlet-class>
</servlet>
<servlet-mapping>
  <servlet- name>RPCAdapter</servlet-name>
  <url-pattern>/RPCAdapter/*</url- pattern>
</servlet-mapping>

向 WEB-INF 文件夾添加 RpcAdapterConfig.xml 文件。RpcAdapterConfig.xml 文件在 IBM Web 2.0 Feature Pack 中提供。

圖 17. 向 WEB-INF 文件夾添加 RpcAdapterConfig.xml 文件。

在 RpcAdapterConfig.xml 文件中映射模擬器服務實現和方法

在整個配置過程中,RPCAdapter 知道 從調用 JSP 中調用哪個實現。在清單 2 中,<pojo> 下的 <name> 值注冊了將在 JSP 中引 用的實現;<method> 下的 <name> 值注冊了將由 JSP 使用的實現方法; <parameter> 下的 <name> 值注冊了將被傳遞到實現方法的輸入值。

清單 2. 定義 所有 pojo、實現、方法和參數

<services>
  <pojo>
     <name>AccountSearchImpl</name>
     <description>com.simulator.service.AccountSearchImpl</description>
     <methods filter="whitelisting">
      <method>
         <name>getAccountsByEquipment</name>
        <description>web  service method to retrieve account information by
        equipment  id</description>
        <parameters>
           <parameter>
            <name>request</name>
             <description>end point for account
             search simulator service</description>
           </parameter>
          <parameter>
             <name>equipId</name>
            <description>the  equipment id used as key for retrieving simulator
             data</description>
          </parameter>
         </parameters>
      </method>
    </methods>
   </pojo>
</services>

客戶端服務層(模擬器)

模擬器客戶端 服務層包含與模擬器 Web 服務交互所需的 Web 服務客戶端和實現類。實現類根據從相關 JSP 中收集的 數據構造一個特定於模擬器的 SOAP 請求,並將信息發送到已映射的模擬器 Web 服務上,該服務由作為 已映射的 WebSphere Environment Provider 值檢索的端點確定。響應對象將由 RPC Adapter servlet 轉換成 JSON 對象,並回送給調用 JSP 中的用戶。

在清單 3 中,equipment.setSim(equipId) 將來自輸入值的請求對象填充到 JSP 中。endPoint 值被定義為 WebSphere Environment Provider 值。

清單 3. 傳遞到模擬器服務的請求對象的例子

public  ESIGetAccountsByEquipmentResponseType getAccountByEquipment (
  HttpServletRequest  request, String endPoint, String equipId) {

String method =  "getAccountsByEquipment";
ESIGetAccountsByEquipmentResponseType rc = new  ESIGetAccountsByEquipmentResponseType();
ESIGetAccountsByEquipmentResponseType req =  new ESIGetAccountsByEquipmentRequestType();
Equipment equipment = new Equipment ();
equipment.setSim(equipId);
req.setEquipment(equipment);

try {

  InitialContext jndiContext = new InitialContext();
  AccountSearch  service = (AccountSearch) jndiContext
    .lookup ("java:comp/env/service/AccountSearch");

  AccountSearchPort port =  (AccountSearchPort)service.getPort(AccountSearchPort.class);
  ((Stub) port)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endPoint);

  rc =  port.getAccountsByEquipment(req);

} catch (java.lang.Exception e) {
   String[] variables = new String[] { e.getLocalizedMessage() };
   java.text.MessageFormat form = new java.text.MessageFormat(
    "Remote system  error occurred, message is [{0}]");
  String formattedText = form.format (variables);
  logger.logp(WsLevel.SEVERE, CLASS_NAME, method, formattedText,  e);
  return rc;
}
logger.exiting(CLASS_NAME, method, rc);
return  rc;

}

模擬器服務層

在模擬器服務層內部,從請求對象中提取出 “transaction” 鍵,然後使用它來指定將要檢索、使用並作為 POJO 響應返回的 XML 文件 。然後,在清單 4 中,從請求對象中提取出 Equipment ID,然後作為 XML 檢索鍵傳遞給處理層。在該 層中,會應用驗證用例所需的業務邏輯,然後返回響應。

同樣在清單 4 中,第一個 try 語句從 請求中傳遞一個鍵,生成器將使用它查找將被轉換為響應 POJO 的 XML 文件。

清單 4. 從請求對 象中構造鍵供數據生成器層定位 Spring XML 文件

  public  ESIGetAccountsByEquipmentResponseType getAccountsByEquipment(
     ESIGetAccountsByEquipmentRequestType getAccountsByEquipmentInput) 
      throws  java.rmi.RemoteException {

  String methodName =  "getAccountsByEquipment";

  // return object
   ESIGetAccountsByEquipmentResponseType rc = new 
   ESIGestAccountsByEquipmentResponseType();

  // request value used for  simulator xml retrieval key
  String sim =  getAccountsByEquipmentInput.getEquipment().getSim();

  if (log.isLoggable (WsLevel.FINER) {
    log.entering(className, methodName);
  }

  try {

    rc = (ESIGetAccountsByEquipmentResponseType)  com.simulator.DataGenerator
        .getDataByBeanId(
             "ESIGetAcountByEquipmentResponseType",
             ACTION_KEY_EQUIPMENT, sim);
    return rc;
  } catch  (org.springframework.beans.factory.BeanDefinitionStoreException ioe) {

     // return default equipment response
    rc =  (ESIGetAccountsByEquipmentResponseType) com.simulator.DataGenerator
         .getDataByDefault("ESIGetAccountsByEquipmentResponseType",
             ACTION_KEY_EQUIPMENT, DEFAULT_EQUIPMENT_CODE);
    log.logp(WsLevel.SEVERE,  className, methodName, ioe
        .getResourceDescription());
     return rc;
  } catch (Exception e) {
    rc.setStatus (getCommonStatusType(e));
    return rc;
  } finally {
    if  (log.isLoggable(WsLevel.FINER)) {
        log.exiting(className,  methodName);
    }
  }
}

處理層

處理層獲得 inbound 鍵,該鍵將用於確認將要檢索的 Spring XML 文件。檢索到文件之後,SpringBeanFactory 將使用 XML 文件並將數據轉換成已定義的 POJO。Spring 將會在所請求的 XML 文件無法定位時拋出一個封裝的 IO Exception。在這種情況下,可以定義並返回默認的 XML 文件,當場景中已經確定了 “默認 ” 行為時,這項處理將很有用。另一方面是引入處理延遲來模擬事務延遲。這種情況下,常量延遲 值會以 WebSphere Environment Provider 值的形式存儲。

在清單 5 中,bf.getBean (clazzName) 根據模擬器服務中的鍵檢索數據 XML。注意此處還有一個延遲注入檢測,使用的是由 WebSphere Envrionment Provider 定義的值。

清單 5. 數據 XML 與延遲注入的檢索示例

// Method used for retrieving spring xml 
public static Object  getDataByBeanId(String clazzName, String action, String key) throws
Exception  {

  String dataFile = null;
  Object response = null;

  // check if service is "enabled" 
  if ((ACCOUNT_SEARCH_ENABLED_KEY !=  null) && (ACCOUNT_SEARCH_ENABLED_KEY != "") 
      &&  (ACCOUNT_SEARCH_ENABLED_KEY.equalsIgnoreCase("FALSE"))) {
    throw new  Exception("service is disabled");
  }

  dataFile = getFile(action,  key);

  com.simulator.SpringContext stsc = new com.simulator.SpringContext  (
      dataFile);

  org.springframework.beans.factory.BeanFactory  bf = stsc
      .getBeanFactory();

  // retrieve pojo
   response = bf.getBean(clazzName);

  // check i latency has been  injected
  if ((ACCOUNT_SEARCH_LATENCY_KEY != NULL) &&  (ACCOUNT_SEARCH_LATENCY_KEY.length() !=
  0)) {
    sleep (ACCOUNT_SEARCH_LATENCY_KEY;
  }

  return response;

數據層

數據層包含已定義的 XML 文件,Spring 框架會使用這些文件並作為 POJO 返回到模擬器服務層 。清單 6 中的 POJO 是一個典型的 JavaBean 例子,它可用於在 Spring 框架內連接數據層與 XML。 POJO 利用了簡單的 getter 和 setter,使用框架將 XML 綁定到 Java bean。

清單 6. 簡單的 JavaBean 定義的例子

* AccountSummaryType.java.. 

package  com.simulator.eo.account.accountsearch;

public class AccountSummaryType {
  private java.lang.String ssn;

  publicAccountSummaryType() {
   }

  public java.lang.String getSsn() {
    return ssn;
  }

  public void setSsn(java.lang.String ssn) {
    this.ssn =  ssn;
  }

清單 7 提供了一個示例 Spring XML,表示清單 6 中所示的 JavaBean 。

清單 7. 用 Spring XML 表示 JavaBean 的例子

<?xml version="1.0"  encoding="UTF-8"?>
<beans xmlns=http://www.springframework.org/schema/beans
    xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
     xsi:schemaLocatin="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  <bean  name="ESIGetAccountsByEquipmentResponseType" 
     class="ESIGetAccountsByEquipmentResponseType" 
      <property  name="accountSummary">
      <bean  class="com.simulator.eo.account.accountsearch.AccountSummaryType">
        <property name="ssn" value="ssn"></property>
      </bean>
      </property>
  </bean>
</beans>

WebSphere Application Server 配置

需要更改 WebSphere Application Server 配置以支持模擬器框架。模擬器利用 WebSphere 的 Resource Environment Provider 存儲模擬器應用程序中使用的值。Resource Environment Provider 的優勢是它允許在 Application 服務器中存儲特定於環境的變量,而不是在屬性文件中存儲。以下的例子演示了模擬器的帳 戶查找服務屬性的配置。這些步驟定義了模擬器 Resource Environment Provider 及其屬性值。可參考 “Using resource environment providers in WebSphere Application Server”。

WebSphere Resource Environment Provider

執行以下步驟安裝 WebSphere Resource Environment Provider:

登錄到 WebSphere 管理控制台並使用左邊的導航功能導航到 Resources >Resource environment providers。

單擊 New 並輸入 Environment Provider 的名稱(即 Simulator Environment Provider)。

圖 18. 定義 Simulator Environment Provider

執行以下步驟安裝 WebSphere Resource Environment Provider – Referenceables:

單擊新的 Environment Provider 的名稱並導航到 Resources > Resource environment providers > Simulator Environment Provider > Referenceables。

單擊 New 以輸入 Factory 和 Class Name。輸入以下內容:

com.simulator.EnvironmentProviderFactory 作為工 廠類名稱

com.simulator.EnvironmentProvider 作為類名

圖 19. 定義 Environment Provider Referenceables 中的工廠和類

按以下步驟安裝 WebSphere Resource Environment Provider - Resource env entries:

單擊 Simulator Environment Provider 的 breadcrumb 條目並導航到 Resources > Resource environment providers > Simulator Environment Provider > Resource env entries。

單擊 New 並 輸入以下信息:

使用 Simulator Configuration 作為名稱

使用 rep/SimulatorConfig 作 為 JNDI 名

使用 Simulator configuration properties 作為描述

圖 20. 定義 resource environment 條目

使用以下步驟配置 WebSphere Resource Environment Provider – Custom Properties:

單擊新創建的 Resource env 條目 “Simulator Configuration” 的標題並導航至 Resources > Resource environment providers > Simulator Environment Provider > Resource env entries > Simulator Configuration >Custom properties。

單擊 New 並輸入表 1 中的信息。結 果將如圖 21 所示。

表 1. 自定義屬性定義的值

名稱 值 描述 是否必需 AccountSearch.Endpoint http://localhost:10000/Simulator/services/A ccountSearch 模擬器端點 否 Simulator.Directory C:\\simulator\\xml\\ 模擬器數據目錄 否 AccountSearch.Latency 500 延遲值 否 AccountSearch.Folder Account\ 數據文件夾 否 AccountSearch.Prefix ACT 文件前綴 否 AccountSearch.Enabled true 支持的狀態 否

圖 21. 定義應用程序使用的自定義屬性

注冊 Resource Environment Reference:WebContent > WEB-INF > edit web.xml adding Resource Environment Reference。

圖 22. web.xml 中的 Resource Environment Reference

現在可以從 Java 對 象或 JSP 的代碼中檢索配置值。在本例中可用來代替屬性文件,因為可通過管理控制台來管理這些值並 使用控制台在整個集群中同步。

結束語

模擬器提供了一種方便的方式來針對並不總是可用 (或者無法支持完整的系統測試需求)的系統進行開發和測試。模擬器框架提供了一種可快速采用模擬器 最佳實踐的機制,包括使用服務指示板監控模擬的和活動的後台服務。在開發過程中,當真實服務不可用 或不可靠時,模擬器是一項顯而易見的選擇,此外,模擬器還可用於功能與性能測試,包括使用延遲注入 對 SLA 建模。模擬器框架最初可能令人感覺過於復雜和耗時,但是歷經多個項目生命周期後,最終證明 它在開發過程中能夠顯著降低項目的整體投入和風險,同時提高單元測試、功能測試、性能測試的質量。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved