閆 黎,白曉虎
(中國空空導(dǎo)彈研究院,河南洛陽 471009)
基于Web的網(wǎng)絡(luò)拓撲圖繪制、監(jiān)控是未來的一個發(fā)展趨勢,通過Web瀏覽器,網(wǎng)管人員能夠快速便捷地了解網(wǎng)絡(luò)的拓撲結(jié)構(gòu)、每個設(shè)備的健康狀況,能夠做到移動辦公,實時監(jiān)控,及時發(fā)現(xiàn)故障,提高網(wǎng)絡(luò)的整體運行環(huán)境。
JGraphx[1]是一個開源的、兼容 Swing 的圖形組件,具有相當(dāng)高的交互性和自動化,是一套為圖定做的組件。其主要用途是應(yīng)用在一些需要表示圖的結(jié)構(gòu)中,比如流程圖、UML、交通線路、網(wǎng)絡(luò)等等。本文將使用其實現(xiàn)網(wǎng)絡(luò)拓撲圖的自動繪制。
a.JGraphx繪圖元素分為3種:節(jié)點(Vertex)、連線(Edge)、端口(Port)。JGraphx使用cell來表示它們,并提供相關(guān)API區(qū)分它們的不同。
b.Applet是用Java語言編寫的小應(yīng)用程序,它們可以直接嵌入到網(wǎng)頁中,并能夠產(chǎn)生特殊的效果。包含Applet的網(wǎng)頁被稱為Java-Powered頁,可以稱其為Java支持的網(wǎng)頁。
c.Web Service[2]是一種面向服務(wù)架構(gòu)的技術(shù),通過標(biāo)準(zhǔn)的Web協(xié)議提供服務(wù),保證不同平臺的應(yīng)用服務(wù)可以互操作。本文中將采用WebService協(xié)議通過瀏覽器與后臺服務(wù)通信。
通過讀取數(shù)據(jù)庫中的相關(guān)業(yè)務(wù)數(shù)據(jù)自動生成拓撲圖。用戶可以對拓撲圖進行修改,并將修改后的拓撲圖以XML形式保存至數(shù)據(jù)庫中,待查看時從數(shù)據(jù)庫中讀取拓撲圖XML并向用戶展示,拓撲圖生成、修改和保存流程如圖1所示。
圖1 拓撲動作流程
采用Applet的方式將JGraphx嵌入至瀏覽器中。在前臺,使用JavaScript與JGraphx通信,達到Web頁面其他元素與JGraphx的交互,實現(xiàn)同步提交、同步更新等。與后臺服務(wù)端的交互采用Web Service?;炯軜?gòu)圖如圖2所示。
圖2 基本架構(gòu)圖
2.3.1 JGraphx嵌入至 Web 瀏覽器
JGraphx是基于Swing的開源工具,在JGraphx工程中新建類并繼承Japplet,重寫Japplet的init()方法[3],將 GraphEditor.java 中 main 方法的代碼復(fù)制至創(chuàng)建的Japplet重寫的init()方法,即可實現(xiàn)從Web瀏覽器訪問JGraphx。
將JGraphx遷移至Applet后,由于JGraphx在打開、保存拓撲圖時,使用到反射、讀取本地文件等,易使后臺產(chǎn)生異常。為了解決此種異常,需對JGraphx進行加密簽名認證,增加其權(quán)限。
2.3.2 JS 與 Applet通信
為了實現(xiàn)頁面表單與Applet中拓撲圖的同步保存,使用JS與Applet交互的方式。
Web頁面中Applet嵌入方式:
<applet name=″appletName″…/>
JS調(diào)用Applet的方法:
window.document.a(chǎn)ppletName.methodName()(方法必須是 public 的,″window.document.″也可以不寫)
注意事項:
在使用JS調(diào)用Applet的方法時,會導(dǎo)致Applet放入JS的安全沙箱內(nèi),如果Applet中采用反射、訪問本地等功能(簽名后的Applet也一樣),則調(diào)用失敗,程序后臺會出現(xiàn)安全性異常。
解決方法:
在Applet中使用 SwingUtilities.invokeLater()或 SwingUtilities.invokeAndWait()調(diào)用核心方法[4]。
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
//業(yè)務(wù)方法
}
}
)
Applet調(diào)用JS的方法:
import netscape.javascript.JSObject;//引 入netscape類
import netscape.javascript.JSException;//可允許在小程序中處理異常事件
win=JSObject.getWindow(this);// 獲 取JavaScript窗口句柄,引用當(dāng)前文檔窗口
doc=(JSObject)win.getMember("document");//訪問JavaScript document對象
form=(JSObject)doc.getMember("text-Form");//訪問JavaScript form對象
textField=(JSObject)form.getMember("text-Field");//訪問 JavaScript text對象
text=(String) textField.getMember("value");//獲取文本區(qū)的值
2.3.3 JGraphx 存儲業(yè)務(wù)數(shù)據(jù)
使用JGraphx繪制的拓撲圖本身與業(yè)務(wù)沒有任何關(guān)聯(lián),無法與實際中的設(shè)備關(guān)聯(lián)。
JGraphx拓撲圖中的每個圖元被設(shè)計為一個cell,cell默認存儲String類型的字符串,并把此值當(dāng)作cell的label顯示在畫板上。
首先通過自定義界面顯示UI實體,將其存儲至cell中,使其可以存儲業(yè)務(wù)數(shù)據(jù)。其次修改mx-Graph的getLabel()顯示方法,避免cell在畫板顯示異常(默認顯示為對象的toString()結(jié)果)。示例代碼:
UIEquipment equit=new UIEquitment();
cell.setVaule(equit);//將業(yè)務(wù)數(shù)據(jù)保存在cell中
2.3.4 JGraphx 的關(guān)系遍歷
當(dāng)Web上的拓撲圖被修改后,在將其存入數(shù)據(jù)庫時需要查找圖中各個節(jié)點之間的關(guān)系,以便于其他業(yè)務(wù)應(yīng)用使用其中的關(guān)系。
從JGraphx生成的XML文件來看,節(jié)點與節(jié)點之間的關(guān)系被存儲在連接線中,而在節(jié)點中并沒有體現(xiàn)。但是在JGraphx的API中可以簡單實現(xiàn)節(jié)點關(guān)系的遍歷。獲取示例代碼:mxGraph graph=getGraph(e);//通過 mxGraph調(diào)用
mxGraphModel model=(mxGraphModel)graph.get-Model();//獲取topo模型
Map < String,Object> map = model.getCells();//獲取所有的節(jié)點和鏈路信息
for(String key :map.keySet())//遍歷所有的節(jié)點和鏈路,如果是節(jié)點,查找與其連接的鏈路,并根據(jù)鏈路API獲取臨節(jié)點信息{
mxCell cell=(mxCell)map.get(key);
if(cell.isVertex())
{
for(int i=0;i < cell.getEdgeCount();i++)//cell.getEdgeCount() 獲取與 cell連接的線條個數(shù)
{mxCell edge = (mxCell)cell.get-EdgeAt(i);
mxCell source=(mxCell)edge.get-Source();//獲取鏈路兩端的資源,示例代碼,忽略掉空指針異常
mxCell target=(mxCell)edge.getTarget();
}
}
}
2.3.5 拓撲圖的保存和讀取
a.文本文件的保存和讀取。
JGraphx提供了多種格式保存繪制成的拓撲圖文件,建議將其保存為mxe格式,此格式內(nèi)部為XML結(jié)構(gòu),可讀性好。
拓撲圖讀取示例代碼:
Documentdocument = mxXmlUtils.parseXml(URLDecoder.decode(value,"UTF-8"));mxCodec codec=new mxCodec(document);
codec.decode(document.getDocumentElement(),editor.getGraphComponent().getGraph().getModel());
拓撲圖保存示例代碼:
mxCodec codec=new mxCodec();
String xml= mxXmlUtils.getXml(codec.encode(graph.getModel()));
b.?dāng)?shù)據(jù)庫的保存和讀取。
JGraphx保存的XML文件將每個節(jié)點、鏈路都封裝為一段以"<mxCell></mxCell>"為根節(jié)點的XML片段,示例如下:
< mxCell id=″2″parent=″1″style="image;image=/com/mxgraph/examples/swing/images/EXCHANGER.png"vertex= ″1″>
< UIEquipment as =″value″ resID ="3f2886ee3c223ea3013c227adad60056"resName=″H3C S5120″/> <! --業(yè)務(wù)數(shù)據(jù)模型轉(zhuǎn)換為XML-->
< mxGeometry as= ″geometry″height= ″50.0″width= ″50.0″x= ″160.0″y= ″200.0″/> < !--節(jié)點的高、寬和具體坐標(biāo),其中坐標(biāo)代表節(jié)點矩形左上角坐標(biāo)-->
</mxCell>
依據(jù)這種XML結(jié)構(gòu),可以將XML拆分為多個XML片段存儲在數(shù)據(jù)庫中,并可實現(xiàn)拓撲圖的關(guān)聯(lián)關(guān)系存儲。當(dāng)需要查看拓撲圖時,通過拓撲圖ID檢索構(gòu)成此圖的所有元數(shù)據(jù),并將節(jié)點元數(shù)據(jù)組裝為XML,圖3為元數(shù)據(jù)數(shù)據(jù)庫模型。
圖3 數(shù)據(jù)庫物理模型圖
2.3.6 告警顯示和閃爍
告警顯示和閃爍是拓撲圖的一個重要功能,本文通過在節(jié)點上覆蓋一個半透明的圖片實現(xiàn)告警顯示功能,并使其按照一定頻率顯示和消失實現(xiàn)閃爍功能。
借助JGraphx的mxCellOverlay類實現(xiàn)告警顯示和閃爍功能,主要代碼如下:
public void paint(Graphics g)//修改 mxCell-Overlay 的 paint()方法[5]
{
Graphics2D gd=(Graphics2D)g;
gd.setComposite(AlphaComposite.getInstance(Al-phaComposite.SRC_OVER,.5f));//設(shè)置透明度
gd.setColor(Color.RED);
gd.drawRect(0,0,getWidth(),getHeight());
gd.fillRect(0,0,getWidth(),getHeight());
}
告警閃爍實現(xiàn)代碼:
Timer timer=new Timer(1000,new BrightListener());//為其設(shè)置一個定時器,按照一定頻率繪圖。
class BrightListener implements ActionListener
{
int j=0;@Override public void actionPerformed(ActionEvent e){
if(j%2==0)
{
alpha=AlphaComposite.getInstance(AlphaComposite.SRC_OVER,.5f);
repaint();
}else
{
alpha=AlphaComposite.getInstance(AlphaC-omposite.SRC_OVER,.0f);//將透明度設(shè)置為0,使圖片消失
repaint(); }
j++;
}
}
2.3.7 自動布局
JGraphx本身提供了多種布局方式,但是其布局方式在默認情況下會出現(xiàn)節(jié)點重疊、連接線短等問題,因此需設(shè)置相關(guān)參數(shù),提供其計算精度,使布局精確化。
有機布局API示例:
mxOrganicLayout layout=new mxOrganicLayout(graph);//獲取mxGraph后,調(diào)用布局構(gòu)造函數(shù)
layout.execute(graph.getDefaultParent());
setRadiusScaleFactor(1.0);//優(yōu)化有機布局算法精度
setApproxNodeDimensions(false);
setEdgeCrossingCostFactor(8000);
setNodeDistributionCostFactor(getNodeDistributionCostFactor()* 5);
setEdgeDistanceCostFactor (getEdgeDistance-CostFactor()* 5);
setEdgeLengthCostFactor(getEdgeLengthCost-Factor()/10);
拓撲效果展示如圖4所示,拓撲效果機房機柜展示如圖5所示。
圖4 拓撲效果展示圖
圖5 拓撲效果機房展示圖
基于Web的JGraphx繪制網(wǎng)絡(luò)拓撲圖,結(jié)合了Java Applet、JavaScript技術(shù),實現(xiàn)了拓撲圖工具的Web監(jiān)控,并支持 Unix、Linux、Windows等多種操作系統(tǒng)。另外,其通過Web Service與服務(wù)端交互,保持服務(wù)端平臺標(biāo)準(zhǔn)性,使JGraphx可以應(yīng)用于更廣的領(lǐng)域。
[1] mxGraph公司.JGraph User Manual[EB/OL].[2012-07-21].http://www.jgraph.com/doc/mxgraph/index_javavis.html.
[2] Oracle公司.JSR181 Web Services Metadata forthe JavaTM[EB/OL].[2005-06-27].http://jcp.org/aboutJava/communityprocess/final/jsr181/index.html.
[3] Elizabeth Sugar Boese.An Introduction to Programming with Java Applets[M].Sudbury:Jones and Bartlett Publishers,2009:20-135.
[4] hgq0011.JS與 Applet交互[EB/OL].[2007-03-27].http://www.iteye.com/topic/65741.
[5] 羅依.Java Swing[M].2版.R&W 組譯.北京:清華大學(xué)出版社,2004:389-432.