OpenNMS技术分析与扩展开发

来源:互联网 发布:sharpdesk软件 编辑:程序博客网 时间:2024/04/30 15:47

OpenNMS技术分析与扩展开发

 

1. 技术分析

OpenNMS用Java语言实现,基于linux系统和Postgres数据库的网络管理系统。系统配置信息通过XML数据存储,网络数据通过JDBC对数据进行持久化,Web采用JSP/Servlet。OpenNMS是一个Open Source Framework,它采用了诸多的开源组件与框架,使用了各种协议的开源实现:

l         OpenNMS采用了xml数据绑定技术(opennms采用的是castor)。根据xml文件的schema定义文件(xsd文件)生成对xml文件到java对象的映射,这样就不需要写解析xml文件的代码而是针对java对象进行操作。因此这些类都是在系统编译过程中由castor包根据xsd文件生成的。(Castor是一个Java开源数据绑定框架,它主要目标是提供Java对象与XML 的绑定,Java到SQL的持久化等.)

l         Cleanimports是对java文件中的无用的imports作清理,并通过配置文件提供的格式对imports代码段进行格式整理。

l         HttpUnit进行模拟HTTP测试。

l         jWebUnit 是基于java的测试网络程序的框架。它提供了一套测试见证和程序导航标准。jWebUnit 有JUnit和HtppUnit实现。

l         Junit单元测试

l         nekohtml解析HTML,Html Tidy对html 字符串进行修正,并做标准化的处理。

l         Avalon主要是一种Server的架构,可以满足配置、日志等服务器程序的需要,

l         Jdhcp,java DHCP的实现。

l         Xerces解析XML,API与实现有:xmlParserAPIs, xml-apis, xercesImpl

l         FOP可以将xml文件转换成pdf,mif,pcl,txt等多种格式以及直接输出到打印机,并且支持使用SVG描述图形。

l         jCIFS,用Java开发的SMB客户端库。

l         ldap-impl,LDAP java实现。

l         smtp.jar pop3.jar,SMTP,POP3协议Java实现。

l         JRobin基于LGPL授权的网络性能监控系统,是RRDTool的一个纯Java实现。

l         joeSNMP,Java SNMP类库。

 

所以,要想扩展(Extending)开发OpenNMS需掌握如下技术(Technologies):

Java 2XML/XSLServletsJSPsRDBMSJMSCastorJoesSNMPRRDTool

 

2. 系统架构

 

图1. OpenNMS系统架构图

l         OpenNMS架构主要包括如下功能:Discovery,CAPSD,Eventd,Actiond,Notifd,Scheduler,Service Monitor(pollers),RTC,Outage Manager,Data Collection,Reporting(Performance Reports,Availability Reports),Web UI

l         流程说明:

1. 总控/调度Classloader

2. 发现轮询

l         能力检查Capability daemon - capability check on nodes

l         动态主机配置协议DHCP daemon - DHCP client for OpenNMS

l         发现Discovery daemon - initial and ongoing discovery互联网控制消息协议(Internet Control Message Protocol或简写ICMP)

3. 配置采集

数据采集Collection daemon - collects datajmxMbean:Collectd extendsServiceDaemon

采集流程:

⑴         Initializing collection daemon 初始化日志加载调度

⑵         Loading collectors"

a)          instantiateCollectors

b)          createScheduler

c)          createEventProcessor

⑶         start

scheduleExistingInterfaces()

⑷         pause

⑸         resume

⑹         stop

 

4. 性能采集

5. 事件

l         通知Notification daemon - external notification of users

l         实时控制RTC manager daemon - real time availability information

l         陷阱SNMP trap daemon – handles SNMP traps

l         阈值Threshold daemon – monitor for threshold values

6. 服务

l         轮询Poller daemon - polls managed nodes/services

7. 运行情况Outage manager daemon - consolidates events

 

3. 扩展开发

3.1. 开发环境

l         采用版本:

OpenNMS-1.2.9-1

l         开发环境与工具:

Redhat Enterprise Linux 5.0JDK1.5Tomcat-4.1.37Eclipse(WTP) Ant1.6.5JDBC2.0JSP1.2Servlet2.3JSTLHTMLXML/XSLrrdtool 1.0及相关的开源组件与框架。

3.2. 配置说明

       OpenNMS可通过XML配置文件来扩展网络配置与定制服务。

1. 自身管理

l         service-configuration.xml

定义OpenNMS本身要启动的服务. 它和VM有关,并且控制哪个服务在哪个VM中开启.

l         jmx-datacollection-config.xml

2. 发现配置

l         discovery-configuration.xml (daemon)

定义要发掘的网络地址范围,(ping sweep)以及逾时,重试次数,以及用来做发掘的执行绪(thread)数目。这个档案也提供 初次发掘间隔时间(initial-sleep-time)和重新发掘间隔时间(restart-sleep-time)。这些数值以毫秒(miliseconds)为单位,用来决定 OpenNMS 执行后,间隔多久要开始针对网络地址清单作发掘;以及每次发掘之间的间隔时间。

<discovery-configuration threads="1" packets-per-second="1"

       initial-sleep-time="300000" restart-sleep-time="86400000"

       retries="3" timeout="800">

       <include-range retries="2" timeout="3000">

              <begin>192.168.0.1</begin>

              <end>192.168.0.254</end>

       </include-range>

       <include-url>file:/usr/local/OpenNMS/source/dist/etc/include</include-url>

</discovery-configuration>

3. 配置性能采集

l         snmp-config.xml

定义snmp采集的节点、版本、read-community、超时、重试次数等

<snmp-config retry="3" timeout="800" read-community="public" write-community="private">

<definition version="v2c">

    <specific>192.168.0.5</specific>

</definition>

<definition retry="4" timeout="2000">

    <range begin="192.168.1.1" end="192.168.1.254"/>

    <range begin="192.168.3.1" end="192.168.3.254"/>

    </definition>

<definition read-community="bubba" write-community="zeke">

    <range begin="192.168.2.1" end="192.168.2.254"/>

</definition>

<definition port="1161">

    <specific>192.168.5.50</specific>

</definition>

</snmp-config>

l         collectd-configuration.xml

透过collectd进程进行数据收集。collectd侦听SNMP服务的NodeGainedService事件,在些它会检查是否存在节点集合中初始的SNMP接口。

<collectd-configuration hreads="5">

<package name="example1">

    <filter>IPADDR IPLIKE *.*.*.*</filter>

        <specific>0.0.0.0</specific>

        <include-range begin="192.168.0.1" end="192.168.0.254"/>

        <include-url>file:/opt/OpenNMS/etc/include</include-url>

        <service name="SNMP" interval="300000" user-defined="false" status="on">

               <parameter key="collection" value="default"/>

               <parameter key="port" value="161"/>

               <parameter key="retry" value="3"/>

               <parameter key="timeout" value="3000"/>

        </service>

        <outage-calendar>zzz from poll-outages.xml zzz</outage-calendar>

     </package>

     <collector service="SNMP" 

  class-name="org.OpenNMS.netmgt.collectd.SnmpCollector"/>

</collectd-configuration>              

l         datacollection-config.xml (daemon)

包含给RRDTool的数据收集信息.

l         poller-configuration.xml (daemon)

用来定义轮询组合(packages)以及设定各种服务的轮询器(pollers)。一个轮询组合内含数种项目,例如网络地址范围,服务,排修时段(outage calendars),和故障时段模式(down time models).

4. 性能阈值

l         thresholds.xml

5. RTC

l         rtc-configuration.xml

定义RTC (Real Time Console)的属性,例如用来计算故障时段百分比的周期(rolling window),web UI刷新周期,以及多久 RTC将更新送至web接口。

6. 事件告警

l         eventconf.xml

定义通用事件识别码(Universal Event Identifiers或UEIs)以及它们的事件屏蔽(masks),描述,记录文件讯息,和严重程度。

l         trapd-configuration.xml (daemon)

定义SNMP trap的埠口(port)。

l         eventd-configuration.xml (daemon)

定义eventd的运作参数,例如逾时值以及监听器执行绪(listener threads)的数量。

l         actiond-configuration.xml (daemon)

在事件(events)产生时所呼叫的外部程序称为(actions). 这个设定档控制最多可以同时 执行的action数量, 以及等待action执行完毕回传结果的逾时值。

l         notifications.xml

定义哪个事件或UEI发出告警, 以及发出告警的途径.

      <notification name="nodeAdded">

      <uei><![CDATA[http://uei.OpenNMS.org/products/bluebird/nodes/nodeAdded]]></uei>

                <rule><![CDATA[IPADDR IPLIKE *.*.*.*]]></rule>

                <destinationPath>Email-Network/Systems</destinationPath>

                <text-message>OpenNMS has discovered a new node named %parm[nodelabel]%.

Please be advised.</text-message>

                <subject>%parm[nodelabel]% discovered.</subject>

      </notification>

l         destinationPaths.xml

用来定义告警的目标路径(destination path), 例如告警应该送给谁, 传送方式用传呼, 电邮, 或者电邮-传呼.

l         notificationCommands.xml

定义如何达成在destinationPaths.xml中所使用的各种联络方式. 这包括了可执行文件的所在位置, 各种联络方式的别名(aliases), 以及特定传送方式尚需的其它信息.

      <command type="email">

                <name>/bin/mail</name>

                <lookup>email</lookup>

                <lookup>mail</lookup>

                <comment>for sending email notifications</comment>

                <argument streamed="false">

                     <substitution>-s</substitution>

                     <switch>-subject</switch>

                </argument>

                <argument streamed="false">

                     <switch>-email</switch>

                </argument>

                <argument streamed="true">

 

                     <switch>-tm</switch>

                </argument>

      </command>

7. 服务管理

l         capsd-configuration.xml (daemon)

对于已经发现的节点(包含由discovery daemon或SNMP所发现的),能够侦测出哪些服务. 它还可定义,若发掘了某些网络地址/网络地址区段,则应该受控或排除在外. 对于没有定义到的其它网络地址,它可用一个预设的状态(管理政策)来规范.

      <capsd-configuration rescan-frequency="86400000"

              management-policy="unmanaged"> 

可以设定"rescan-frequency"(重新扫描网络的频率).这个设定决定了时间间隔多久需重新扫描网络上的设备, 并且重新确认其上有哪些服务. 单位是毫秒,默认值是86400000,也就是24小时.

l         outage-configuration.xml

定义(服务)中断管理(outage manager)可以有多少个写入执行绪(writer threads)。

8. 数据库

l         create.sql database-schema.xml

一般来说, 在安装过程中, 指令执行install.pl去呼叫create.sql, 来建立OpenNMS数据库. create.sql是数据库脚本. OpenNMS数据库的schema定义在database-schema.xml; 执行筛选时,系统会参照它来执行数据库查询.          

l         OpenNMS-database.xml

数据库class、url、用户名、密码,这个配置文件用来定义OpenNMS使用的数据库类型,名称,认证,以及套用的模板。

9. 其他

l         users.xml / groups.xml

存放使用者的信息,例如他们的联络方式,所属群组和会员资格。这些档案的信息是用来做web UI的身份认证及告警所需的联络方式。

l         log4j.properties

定义log4j的属性。它包括记录文件大小,更迭(rotation),以及各类别记录文件的记录层级。

l         magic-users.properties

优先权高于users.xml,它包含了一些特殊使用者的信息。这是刻意用来控制和web UI互动的某些功能之权限。

l         AvailabilityReports.xsl SVGAvailReport.xsl PDFAvailReport.xsl

这三个档案的信息是关于如何将可用性报表转换成PDF格式.

l         viewsdisplay.xml

这个档案定义在web UI中显示时, 各个类别的呈现方式. 这些类别则是定义在views.xmlcategories.xml.

 

3.3. 扩展服务

3.3.1 介绍

Daemon(capsd)主要负责扫描发现网络接口,发现discovery daemon(守护进程),为Services/Protocols提供支持并且更新到Database中。根据上次检查是否有任何额外的服务有受管理的接口的能力,Capsd也将定期重新扫描管理接口。

    Poller daemon在定期的配置区间中,负责检查每个受管接口的每个状态,如果服务的状态从上次一个适当的事件已改变,表明接口将产生新的服务的状态。

    OpenNMS提供了一个简单快速的框架用来扩展设置缺省服务与协议,为了扩展OpenNMS管理一个可定制的服务或协议需满足如下要求:

l         编写代码capsd plugin(插件)测试网络接口是否有支持期望的协议或服务。

l         添加一个<protocol plugin>元素,在$OPENNMS_HOME的/etc/capsd-configuration.xml config定义新的服务。

l         编写代码poller插件,在某一特定的网络接口,监测当前期望的协议或服务的状态。

l         在$OPENNMS_HOME的/etc/capsd-configuration.xml config配置文件中添加<service>和<monitor>元素定义新的调用服务。

 

3.3.2 创建Daemon(Capsd) Plugin

l         编写Plugin

    Capsd使用plugin执行设备的性能检测,一个Plugin是一个实现org.opennms.netmgt.capsd.Plugin接口的Java类。下列接口中的方法必须实现:

public interface Plugin {

    /**

     * Returns the name of the protocol that this plugin checks on the target

     * system for support.

     * @return The protocol name for this plugin.

     */

    public String getProtocolName();

 

    /**

     * Returns true if the protocol defined by this plugin is supported. If the protocol is not supported then a false value is returned tothe caller.

     * @param address The address to check for support.

     * @return True if the protocol is supported by the address.

     */

    public boolean isProtocolSupported(InetAddress address);

 

    /**

     * Returns true if the protocol defined by this plugin is supported. If the protocol is not supported then a false value is returned tothe caller.

     * The qualifier map passed to the method is used by the plugin to return

     * additional information by key-name. These key-value pairs can be added to

     * service events if needed.

     * @param address  The address to check for support.

     * @param qualifiers The map where qualification are set by the plugin.

     * @return True if the protocol is supported by the address.

     */

    public boolean isProtocolSupported(InetAddress address, Map qualifiers);

}

注:FTP plugin位于src/services/org/opennms/netmgt/capsd/FtpPlugin.java下。

    在运行时,性能daemon调用isProtocolSupported()方法。此方法是每一加载的plugin通过它java.net.InetAddress对象的每一个被发现的守护daemon,发现任何支持此接口的服务将通过接结点标识符与IP地址增加到ifservices数据表中。

 

l         集成Plugin

在初始化过程中,性能daemon读取capsd-configuration.xml配置文件并插入任何新服务到services数据表中,此外,在初始化过程中,性能daemon使用plugin类名信息加载定义在capsd-configuration.xml中的每一项plugin。

编辑capsd-configuration.xml新增<protocol plugin>元素可添加一个新的服务,<protocol plugin>元素定义服务名字,plugin类名,及plugin的任何具体属性。

    如下是编辑capsd-configuration.xml 文件增加一个FTP service:

    <protocol-plugin protocol="FTP"

class-name="org.opennms.netmgt.capsd.FtpPlugin"

scan="on">

        <property key="userid" value="ftp"/>

        <property key="password" value="anonymous@"/>

    </protocol-plugin>

在userid,ftp和password,anonymous@是组“名称-值”对通过isProtocolSupported() 方法中的java.util.Map参数传递给Plugin。

 

3.3.3 创建Poller Plugin

(1)  编写Poller Plugin

Poller daemon使用Poller Plugin轮询受管制接口所支持的服务当前状态。一个Poller Plugin是一个实现org.opennms.netmgt.poller.monitors.ServiceMonitor接口的Java类。此接口定义的如下方法必须在plugin中实现:

  

    public void initialize(java.util.Map parameters);

   

    Called by the poller daemon following instantiation of the

    plugin during startup.  If during initialization the plugin detects

    a critical error (such as a missing library) it can throw a

    java.lang.RuntimException.  If the plugin throws an exception during

    initialization the poller daemon will disable the plugin.  

   

public void release();

 

    Called by the poller daemon during shutdown.  This provides a

    mechanism for the plugin to release any acquired resources.

 

public void initialize(org.opennms.netmgt.poller.NetworkInterface iface);

 

    Called by the poller daemon whenever the poller learns of a new

    interface which supports the service polled by the plugin. 

    If desired, configuration information can be associated with the

    interface at this time prior the poller actually scheduling

    the interface.  If the plugin throws an exception during interface

    initialization the poller daemon will log an error and discard

    the interface

   

public void release(java.net.NetworkInterface iface);

 

    Called by the poller daemon whenever an interface is being removed

    from the scheduler. For example, if a service is determined as being

    no longer supported by an interface then this method will be invoked

    to cleanup any information associated with that interface. This

    gives the implementor of the interface the ability to serialize any

    data prior to the interface being discarded.  If an exception is

    thrown during the release the exception will be logged, but the

    interface will still be discarded for garbage collection.

 

public int poll(java.net.NetworkInterface iface,

              org.opennms.netmgt.utils.EventProxy eproxy,

              java.util.Map parameters);

 

    Called by the poller daemon each time an interface requires a check

    to be performed as defined by the poller scheduler.  The poll()

method is passed the interface to check, a reference to an required by the plugin aside from the standard available/unavailable

    generated by the poller daemon.  Additionally, a java.util.Map

    is passed which may be used to access any service specific

    configuration values as defined in the poller-configuration.xml

    config file.

(2)  Poller Plugin集成

在初始化时,poller daemon进程读取poller-configuration.xml配置文件,并使用plugin类名信息加载定义在capsd-configuration.xml文件中的<monitor>元素的每一项plugin。参数相关的每个服务所定义的<service>要素的配置文件,也是读取和使用由poller ,以确定如何往往是一个特别的服务是要受访者为服务范围内的围护方案。

              编辑poller-configuration.xml新增<service>元素可添加一个新的服务,<service>元素定义服务名称,多少时间间隔与预定时间,参数列表需定义在<parameter>元素中。配置参数将通过poll()方法中的java.util.Map传递给plugin。

如下是配置一个FTP的poller-configuration.xml:

<service name="FTP" interval="300000">

              <parameter key="timeout" value="3000"/>

              <parameter key="port" value="21"/>

              <parameter key="userid" value="ftp"/>

              <parameter key="password" value="anonymous@"/>

</service>

下一步poller plugin类名是必须要定义的,在poller-configuration.xml文件中添加一个新的<monitor>元素,在这个元素中说明服务名称与类名:

<monitor service="FTP" class-name="org.opennms.netmgt.poller.FtpMonitor"/>

 

(3)  配置文件

l         访问OpenNMS Database

OpenNMS数据库配置信息中指定的美元$OPENNMS_HOME的/etc/opennms-database.xml文件中,这个文件定义了数据库名称,用户名和密码。如果一个poller类需要访问数据库是,则org.opennms.netmgt.config.DatabaseConnectionFactory可能被用来获取数据库连接。

DatabaseConnectionFactory类通过单例方式来获取数据库配置信息。此类提供了一个方便获取数据库连接的方法,如下的代码片段展示怎么用DatabaseConnectionFactory来加载数据库配置从而取出连接。

public static synchronized void init() throws IOException, MarshalException, ValidationException, ClassNotFoundException {

        if (m_loaded) {

            // init already called - return

            // to reload, reload() will need to be called

            return;

        }

        FileInputStream in = null;

        Database database = null;

        try {

File cfgFile = ConfigFileConstants.getFile(ConfigFileConstants.DB_CONFIG_FILE_NAME);

        String configFile = cfgFile.getPath();

        Class dsc = Database.class;

 

        in = new FileInputStream(configFile);

        // Set the system identifier for the source of the input stream.

        // This is necessary so that any location information can

        // positively identify the source of the error.

        //

        InputSource dbIn = new InputSource(in);

        dbIn.setSystemId(configFile);

 

        // Attempt to load the database reference.

        //

        database = (Database) Unmarshaller.unmarshal(dsc, dbIn);   

        DbConfiguration dbConfig = new DbConfiguration(database);

            m_singleton = (m_legacy

                    ? (DbConnectionFactory) new LegacyDbConnectionFactory(dbConfig)

: (DbConnectionFactory) new C3P0DbConnectionFactory(dbConfig)

                    );

            m_loaded = true;

        } finally {

        if (in != null) in.close();

           }

       }

注:位于org.opennms.netmgt.poller.monitors.SnmpMonitor的poller plugin就使用了DatabaseConnectionFactory

l         访问SNMP配置信息

SNMP配置信息存放在$OPENNMS_HOME/etc/snmp-config.xml文件中。此文件定义community strings,重试(retries),超时(timeout),和SNMP版本信息。

如果一个基于SNMP的poller正在写入org.opennms.netmgt.config.SnmpPeerFactory可用于找到JoeSNMP org.opennms.protocols.snmp.SnmpPeer对象为特定接口的IP地址的基于SNMP-config.xml内容。如果一个具体项目在snmp-config.xml中无法找到一个默认SnmpPeer对象,则将被退回。 一个已封装某个特定的IP地址的SNMP配置相关的信息SnmpPeer对象可以通过远程节点建构一个SNMP session(org.opennms.protocols.snmp. SnmpSession)。可以参考JoeSNMP文档进一步了解SNMP peer 对象与session。

SnmpPeerFactory类使用单例方式加载SNMP配置信息,此类为一提供网络地址的服务提供方便取得SnmpPeer对象。

       如下代码片段展现怎么使用SnmpPeerFactory类加载SNMP配置和为指定的网络地址取得一个SnmpPeer对象。

public static synchronized void init() throws IOException, MarshalException, ValidationException {

        if (m_loaded) {

            // init already called - return

            // to reload, reload() will need to be called

            return;

        }

 

File cfgFile = ConfigFileConstants.getFile(ConfigFileConstants.SNMP_CONF_FILE_NAME);

ThreadCategory.getInstance(SnmpPeerFactory.class).debug("init: config file path: " + cfgFile.getPath());

        m_singleton = new SnmpPeerFactory(cfgFile.getPath());

        m_loaded = true;

    }

       注:位于org.opennms.netmgt.poller.monitors.SnmpMonitor的poller plugin就使用了SnmpPeerFactory

 

3.4. Web UI设计

OpenNMS框架逻辑上采用了MVC架构,准确来说是JSP MVC Model 1,采用此架构的主要理念是尽量把逻辑与表示分离,这有利于系统健壮性,代码重用和结构清晰,便于重新设计,并长期维持。在OpenNMS中MVC各部分主要代表如下:

 

图2.MVC架构图

l         视图(JSP)

OpenNMS的页面通过Model请求回来的内容以HTML,XML/XSL,图表等形式呈现给客户端。

l         控制器(Servlet)

OpenNMS的控制器采用Servlet方式的,配置在web.xml文件中,用来接受用户的输入并调用模型和视图去完成用户的需求。所以当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后用确定用哪个视图来显示模型处理返回的数据。

l         模型(Bussiness Object/Java Bean)

模型表示企业数据和业务规则。模型允许重用相同的代码跨数个不同的用户界面组件。由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。有很多很好的例子,如:PerformanceModel, RealTimeDataModel,和OutageModel。每个这些模型所使用的三个或三个以上/ Servlets或jsps。

       注:OpenNMS1.2.9版本采用这种经典古老的JSP/Servlet+JavaBean+JDBC的技术与MVC Model1这种方式来开发,从一定的程序上增加了程序员修改页面的复杂度。我们可以加入JSTLStrutsWeb框架技术来增强其Web应用开发。

 

3.2. 部署结构

       下图是OpenNMS的部署目录,所有的class文件将打包成jar包,如:opennms_common.jar, opennms_core.jar, opennms_install.jar, opennms_joesnmp.jar, opennms_services.jar,

opennms_web.jar。所有的页面部署在opennms根目录下。

整个项目通过opennms.xml文件关联部署到tomcat/webapps目录下。

 

图3. OpenNMS部署结构图

 

 

0 0
原创粉丝点击