|
前言
既有资产 ( 系统 ) ,是指部署在企业基础架构中的现有 IT 资产。通常,它与企业正在运行的业务过程结合,对推动企业完成既定的业务目标、实现相关的业务价值,有着重要的意义。怎样盘活既有资产,重用已有的代码,将它们向新的 IT 技术平台迁移和转换,提升既有资产的价值,是越来越多的 IT 架构师和技术人员非常重视的问题。开发和转换的前提是分析和理解既有资产,很多既有资产的实现是基于传统的 IT 技术,例如:COBOL 是企业实现业务应用的最重要的方式。目前,全球大约存在至少 2000 亿行 COBOL 代码,并且以每年 50 亿行的速度递增。因此,本文使用 IBM WSAA (WebSphere Studio Asset Analyzer) 作为资产的统计和分析工具,探讨了使用 WSAA API,开发客户端程序,分析和获取目标资产,包括资产的 Schema 及源代码。
用例说明
本文样例是一个经过裁剪的零部件订单查询服务。在一个零售企业中,该服务可以为用户提供零部件订单及价格的查询,主要包含两部分功能:检查部件订单和检查部件价格。它们实现的 COBOL 代码是由 CICS 应用提供,被注册到 WSAA demo server 上进行管理和分析,用户可以通过特定的接口获取它们。
图 1. 用例图
开发技术
WSAA 介绍
在实现上述场景中,作者使用 WSAA 作为资产的目录和分析工具。WSAA 是 IBM 针对企业资产分析管理需求提供的一个产品。它能够自动地发现和分析既有资产,提供应用程序构件的及时更新信息,从而缩短新的开发人员的学习周期,降低资产转型开发的复杂度。
WSAA 可以对企业信息系统的不同应用组成部分进行扫描和分析。目前主要针对两大类:MVS 资产(针对大机应用)和分布式资产(针对 J2EE 应用)。扫描后的结果会被保存在 DB2 数据库中,用户可以通过提供的 Web 浏览器接口直接访问这些信息。下面是访问 WSAA server 的 Web 页面:
图 2. WSAA explore 页面
通过使用数据库保存的信息,用户可以利用 WSAA 提供的接口作进一步的代码变化影响分析,也可以找到数据库中特定的代码资产,查看它们的目录分类信息、程序的结构以及具体的代码内容。如图 2 所示,用户可以选择一个具有合适粒度的资产,例如:对于一段 COBOL 程序,然后选择对它采取的动作:查看程序结构。
图 3. WSAA 中的 COBOL 程序结构图
WSAA 是一个对资产的静态分析工具,如果需要对资产进行深度的分析、重组和转换,在既有资产上进行开发,需要和其他产品集成,例如:使用 WDz (Websphere Development for Z system),可以进行资产开发和重组,按照业务目标,编排业务流程,进行接口和消息的映射,并最终生成可部署代码和接口描述文件。
WSAA API 介绍
在本样例中,作者使用 WSAA 提供的 API,来获取资产的源文件。WSAA 对外提供了 Web Services, 允许用户在 J2EE 环境下,开发客户端,使用 JAX-RPC 方式获取 WSAA 扫描和分析的资产,包含资产在 WSAA 上的 Schema 对象和源代码文件。这个 Web Service 的 WSDL 的结构如图 3 所示:
图 4. WSAA 提供的 Web Services Interface 定义
在这个 Web Service 中,提供了一些对既有资产的操作,例如:使用“login()”方法可以建立访问 service 的 session;使用“getAllAssetTypes()”方法可以获取 WSAA 所能识别的资产类别;使用“getAssets()”方法可以按照特定的参数,获得相关的资产对象。通过得到的对象,使用“getAttributeValues()”方法,可以获取相关的属性值,例如:对于 File 类型的资产,它的源代码是作为这个对象的属性值存在的,可以通过上述方式获取。
通过 Web Services 获得的资产对象,具有特定的 Schema,如图 4 所示。其中,最为关键的几个元素及描述分别是:
-
WsaaAsset
“WsaaAsset”对应的实例是通过 Web service 获取的资产对象,该对象记录了资产的信息和状态。资产相关属性“WsaaAssetAttributeValue”使用 Map 进行存储,作为类“WsaaAsset”的成员对象。
-
WsaaAssetKey
对于每一个“WsaaAsset”对象,都包含了一个“WsaaAssetKey”,它标识了这个对象的唯一性;同时,也可以通过“WsaaAssetKey”获取对应的“WsaaAsset”。
-
WsaaAssetType
“WsaaAssetType”可以作为描述“WsaaAsset”的元模型,它约束了符合一个特定类型的资产,应该具有哪些属性和关联。
-
WsaaAssetAttributeValue
“WsaaAssetAttributeValue”作为一个“WsaaAsset”对象的属性,它包含了属性的名字和它对应的值。例如:“asset name”,“site name”,“source location”等都是描述资产的属性。
图 5. Asset Model 类图
实现细节
下列步骤描述了使用 WSAA Web Services Interface,开发程序,从 WSAA server demo 上获取 COBOL 资产对象及源代码。
1. 定义客户端接口
定义了一个访问 WSAA Web Services 的接口:WsaaAssetStrategy.java
// set the access url
public void setWsaaServiceURL(String url) throws Exception;
// set user/pwd of WSAA to get the access token
public void setWsaaServiceUserPwd(String user,String pwd) throws Exception;
// get WSAA assets according to different types
public WsaaAsset[] getWsaaAssets() throws Exception;
// connect WSAA demo server
public WsaaAuthToken connectWSAA() throws Exception;
// get related WSAA assets for the specified asset
public List getRelatedWsaaAsset(WsaaAssetKey key) throws Exception;
// set asset type
public void setAssetType(String assetType);
|
2. 实现客户端类
创建了一个实现上述接口的类:COBOLFileAssetStrategy.java,用于获取 COBOL 程序和文件,步骤如下:
(1) 设置访问的 url、username 和 password,建立与 server 的连接。其中,访问 WSAA demo server 提供的 Web protected static WsaaServiceProxy proxy = null;
protected static WsaaAuthToken token = null;
protected String wsaauser = null;
protected String wsaapwd = null;
public void setWsaaServiceURL(String url) {
proxy.setEndpoint(url);
}
public void setWsaaServiceUserPwd(String user, String pwd) {
wsaauser = user;
wsaapwd = pwd;
}
public WsaaAuthToken connectWSAA() throws Exception {
try{
WsaaAuthToken token = proxy.login(wsaauser,wsaapwd);
return token;
}catch (Exception e){
throw e;
}
}
|
(2) 通过建立连接,输入资产类型,获取资产对象。对于 COBOL 资产,在 WSAA 上有两种分类方式:基于文件的“File”和基于程序的“Program”。所以,选择哪种类型的 COBOL 资产作为查询条件,查询的结果是不同的。此外,这两种类型的资产,它们的属性也有差异。下面代码的功能是关于怎样获取 COBOL 资产。
protected int eachPageAssetNum = 500;
private static final String ATTR_IDENTITY = "Language";
private static final String ATTR_IDENTITY_VALUE = "COB";
public WsaaAsset[] getWsaaAssets() throws Exception{
try{
if(token==null)
token = proxy.login(wsaauser,wsaapwd);
WsaaAssetType[] types = proxy.getAllAssetTypes(token);
String[] attributeNames = null;
for (int i=0;i<types.length;i++)
{
// assetType: File or Program
if (types[i].getName().trim().equalsIgnoreCase(assetType))
attributeNames = types[i].getAttributeNames();
}
// specify query condition
WsaaQuery query = new WsaaQuery();
query.setRequestedAttributeNames(attributeNames);
query.setAssetTypeName(assetType);
query.setNamePattern("*");
int count = proxy.getAssetCount(token,query);
WsaaPagingData pd = new WsaaPagingData();
WsaaAsset[] assets = null;
//specify page number
int pages = count/ eachPageAssetNum +1;
Vector cobolAsset = new Vector();
for (int pageIndex =1; pageIndex<=pages; pageIndex++){
pd.setPageNumber(pageIndex);
pd.setPageSize( eachPageAssetNum);
assets = proxy.getAssets(token, query, pd);
filterCOBOLAssets(assets, cobolAsset);
}
assets = (WsaaAsset[])(cobolAsset.toArray(new
WsaaAsset[cobolAsset.size()]));
return assets;
}catch (Exception e){
e.printStackTrace();
throw (e);
}
}
|
(3) 对于按照“File”类型或者“Program”类型查询得到的资产,需要进行过滤,从而得到符合要求的 COBOL 程序资产。
public void filterCOBOLAssets(WsaaAsset[] assets, Vector cobolAsset)
{ for (int i=0;i<assets.length;i++){
WsaaAsset asset = assets[i];
//filter asset: only COBOL file would be kept
WsaaAssetAttributeValue[] attrValues =
asset.getAttributeValues();
for (int j=0;j<attrValues.length;j++){
WsaaAssetAttributeValue attr = attrValues[j];
if (attr.getName().equalsIgnoreCase(ATTR_IDENTITY) &&
attr.getValue().equalsIgnoreCase(ATTR_IDENTITY_VALUE)){
cobolAsset.add(asset);
break; }
}
}
}
|
(4) 通过得到的资产对象,获取其属性值。对于 COBOL file,可以通过 FileSource 属性得到对应的源代码。
private StringBuffer getCOBOLFileSourceContent(WsaaAsset asset)
{
StringBuffer dump = new StringBuffer();
WsaaAssetAttributeValue[] attribteValues = asset.getAttributeValues();
for (int i = 0; i < attribteValues.length; i++) {
if(attribteValues[i].getName().equals("FileSource"))
{
dump.append(attribteValues[i].getValue());
break;
}
}
return dump;
}
|
对于 COBOL program,Web Services 没有提供可以获取源代码的方法,所以只能通过访问 WSAA server,映射到对应的 Web page,将显示的源代码通过 Http 的方式下载。
(5) 同时,可以根据 asset key,获取与该资产相关联的其他资产。
public List getRelatedWsaaAsset(WsaaAssetKey key) throws Exception
{
List relatedAssets = new ArrayList();
WsaaAssetKey[] relatedKeys = proxy.getRelatedAssets(token, key,
"FilesNeededToBuild");
for (int j =0;j<relatedKeys.length;j++){
WsaaAssetKey relKey = relatedKeys[j];
WsaaAsset relAsset = proxy.getAsset(token, relKey);
relatedAssets.add(relAsset);
}
return relatedAssets;
}
|
通过以上代码实现,可以获取经过 WSAA 扫描和分析的资产及其源代码文件,WSAA 对外提供的 Web Services 还提供了其他的查询功能,用户可以在自己的实践中体验。
结论
本文介绍了 WSAA 作为资产分析和统计的工具,探讨了使用 WSAA API 开发程序,获取资产的技术细节,增强了读者对 WSAA 的功能、接口和资产模型的理解,可以作为实现既有资产分析和抽取的一种样例实践。
参考资料 学习
获得产品和技术
讨论
|