闫 黎,白晓虎
(中国空空导弹研究院,河南洛阳 471009)
基于Web的网络拓扑图绘制、监控是未来的一个发展趋势,通过Web浏览器,网管人员能够快速便捷地了解网络的拓扑结构、每个设备的健康状况,能够做到移动办公,实时监控,及时发现故障,提高网络的整体运行环境。
JGraphx[1]是一个开源的、兼容 Swing 的图形组件,具有相当高的交互性和自动化,是一套为图定做的组件。其主要用途是应用在一些需要表示图的结构中,比如流程图、UML、交通线路、网络等等。本文将使用其实现网络拓扑图的自动绘制。
a.JGraphx绘图元素分为3种:节点(Vertex)、连线(Edge)、端口(Port)。JGraphx使用cell来表示它们,并提供相关API区分它们的不同。
b.Applet是用Java语言编写的小应用程序,它们可以直接嵌入到网页中,并能够产生特殊的效果。包含Applet的网页被称为Java-Powered页,可以称其为Java支持的网页。
c.Web Service[2]是一种面向服务架构的技术,通过标准的Web协议提供服务,保证不同平台的应用服务可以互操作。本文中将采用WebService协议通过浏览器与后台服务通信。
通过读取数据库中的相关业务数据自动生成拓扑图。用户可以对拓扑图进行修改,并将修改后的拓扑图以XML形式保存至数据库中,待查看时从数据库中读取拓扑图XML并向用户展示,拓扑图生成、修改和保存流程如图1所示。
图1 拓扑动作流程
采用Applet的方式将JGraphx嵌入至浏览器中。在前台,使用JavaScript与JGraphx通信,达到Web页面其他元素与JGraphx的交互,实现同步提交、同步更新等。与后台服务端的交互采用Web Service。基本架构图如图2所示。
图2 基本架构图
2.3.1 JGraphx嵌入至 Web 浏览器
JGraphx是基于Swing的开源工具,在JGraphx工程中新建类并继承Japplet,重写Japplet的init()方法[3],将 GraphEditor.java 中 main 方法的代码复制至创建的Japplet重写的init()方法,即可实现从Web浏览器访问JGraphx。
将JGraphx迁移至Applet后,由于JGraphx在打开、保存拓扑图时,使用到反射、读取本地文件等,易使后台产生异常。为了解决此种异常,需对JGraphx进行加密签名认证,增加其权限。
2.3.2 JS 与 Applet通信
为了实现页面表单与Applet中拓扑图的同步保存,使用JS与Applet交互的方式。
Web页面中Applet嵌入方式:
<applet name=″appletName″…/>
JS调用Applet的方法:
window.document.appletName.methodName()(方法必须是 public 的,″window.document.″也可以不写)
注意事项:
在使用JS调用Applet的方法时,会导致Applet放入JS的安全沙箱内,如果Applet中采用反射、访问本地等功能(签名后的Applet也一样),则调用失败,程序后台会出现安全性异常。
解决方法:
在Applet中使用 SwingUtilities.invokeLater()或 SwingUtilities.invokeAndWait()调用核心方法[4]。
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
//业务方法
}
}
)
Applet调用JS的方法:
import netscape.javascript.JSObject;//引 入netscape类
import netscape.javascript.JSException;//可允许在小程序中处理异常事件
win=JSObject.getWindow(this);// 获 取JavaScript窗口句柄,引用当前文档窗口
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");//获取文本区的值
2.3.3 JGraphx 存储业务数据
使用JGraphx绘制的拓扑图本身与业务没有任何关联,无法与实际中的设备关联。
JGraphx拓扑图中的每个图元被设计为一个cell,cell默认存储String类型的字符串,并把此值当作cell的label显示在画板上。
首先通过自定义界面显示UI实体,将其存储至cell中,使其可以存储业务数据。其次修改mx-Graph的getLabel()显示方法,避免cell在画板显示异常(默认显示为对象的toString()结果)。示例代码:
UIEquipment equit=new UIEquitment();
cell.setVaule(equit);//将业务数据保存在cell中
2.3.4 JGraphx 的关系遍历
当Web上的拓扑图被修改后,在将其存入数据库时需要查找图中各个节点之间的关系,以便于其他业务应用使用其中的关系。
从JGraphx生成的XML文件来看,节点与节点之间的关系被存储在连接线中,而在节点中并没有体现。但是在JGraphx的API中可以简单实现节点关系的遍历。获取示例代码:mxGraph graph=getGraph(e);//通过 mxGraph调用
mxGraphModel model=(mxGraphModel)graph.get-Model();//获取topo模型
Map < String,Object> map = model.getCells();//获取所有的节点和链路信息
for(String key :map.keySet())//遍历所有的节点和链路,如果是节点,查找与其连接的链路,并根据链路API获取临节点信息{
mxCell cell=(mxCell)map.get(key);
if(cell.isVertex())
{
for(int i=0;i < cell.getEdgeCount();i++)//cell.getEdgeCount() 获取与 cell连接的线条个数
{mxCell edge = (mxCell)cell.get-EdgeAt(i);
mxCell source=(mxCell)edge.get-Source();//获取链路两端的资源,示例代码,忽略掉空指针异常
mxCell target=(mxCell)edge.getTarget();
}
}
}
2.3.5 拓扑图的保存和读取
a.文本文件的保存和读取。
JGraphx提供了多种格式保存绘制成的拓扑图文件,建议将其保存为mxe格式,此格式内部为XML结构,可读性好。
拓扑图读取示例代码:
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.数据库的保存和读取。
JGraphx保存的XML文件将每个节点、链路都封装为一段以"<mxCell></mxCell>"为根节点的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″/> <! --业务数据模型转换为XML-->
< mxGeometry as= ″geometry″height= ″50.0″width= ″50.0″x= ″160.0″y= ″200.0″/> < !--节点的高、宽和具体坐标,其中坐标代表节点矩形左上角坐标-->
</mxCell>
依据这种XML结构,可以将XML拆分为多个XML片段存储在数据库中,并可实现拓扑图的关联关系存储。当需要查看拓扑图时,通过拓扑图ID检索构成此图的所有元数据,并将节点元数据组装为XML,图3为元数据数据库模型。
图3 数据库物理模型图
2.3.6 告警显示和闪烁
告警显示和闪烁是拓扑图的一个重要功能,本文通过在节点上覆盖一个半透明的图片实现告警显示功能,并使其按照一定频率显示和消失实现闪烁功能。
借助JGraphx的mxCellOverlay类实现告警显示和闪烁功能,主要代码如下:
public void paint(Graphics g)//修改 mxCell-Overlay 的 paint()方法[5]
{
Graphics2D gd=(Graphics2D)g;
gd.setComposite(AlphaComposite.getInstance(Al-phaComposite.SRC_OVER,.5f));//设置透明度
gd.setColor(Color.RED);
gd.drawRect(0,0,getWidth(),getHeight());
gd.fillRect(0,0,getWidth(),getHeight());
}
告警闪烁实现代码:
Timer timer=new Timer(1000,new BrightListener());//为其设置一个定时器,按照一定频率绘图。
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);//将透明度设置为0,使图片消失
repaint(); }
j++;
}
}
2.3.7 自动布局
JGraphx本身提供了多种布局方式,但是其布局方式在默认情况下会出现节点重叠、连接线短等问题,因此需设置相关参数,提供其计算精度,使布局精确化。
有机布局API示例:
mxOrganicLayout layout=new mxOrganicLayout(graph);//获取mxGraph后,调用布局构造函数
layout.execute(graph.getDefaultParent());
setRadiusScaleFactor(1.0);//优化有机布局算法精度
setApproxNodeDimensions(false);
setEdgeCrossingCostFactor(8000);
setNodeDistributionCostFactor(getNodeDistributionCostFactor()* 5);
setEdgeDistanceCostFactor (getEdgeDistance-CostFactor()* 5);
setEdgeLengthCostFactor(getEdgeLengthCost-Factor()/10);
拓扑效果展示如图4所示,拓扑效果机房机柜展示如图5所示。
图4 拓扑效果展示图
图5 拓扑效果机房展示图
基于Web的JGraphx绘制网络拓扑图,结合了Java Applet、JavaScript技术,实现了拓扑图工具的Web监控,并支持 Unix、Linux、Windows等多种操作系统。另外,其通过Web Service与服务端交互,保持服务端平台标准性,使JGraphx可以应用于更广的领域。
[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 组译.北京:清华大学出版社,2004:389-432.