OpenNMS 集成动手实践
现在准备将新的“CLICKMETER”服务集成进 OpenNMS。要做到这一点,将创建用于功能守护程序( capsd )的插件和用于轮询器守护程序( pollerd )的监控程序。
用于 OpenNMS 发现的 ClickMeterPlugin
在源码分发中提供了功能守护程序插件的代码,它在 org.opennms.netmgt.capsd.ClickMeterPlugin 类中。我们知道该插件必须实现 org.opennms.netmgt.capsd.Plugin 接口。清单 1 显示了从 AbstractPlugin 派生而来的这个类。这个 OpenNMS 所提供的抽象类提供了两个抽取参数的方法( getKeyedInteger() 和 getKeyedString() ),这两个参数对我们的编码会有帮助。
清单 1. ClickMeterPlugin 管理类
2 private static final String PROTOCOL_NAME = "CLICKMETER";
3 private static final int DEFAULT_PORT = 8082;
4 private final static int DEFAULT_RETRY = 0;
5 private final static int DEFAULT_TIMEOUT = 5000; // in milliseconds
6
清单 2 中代码是 getProtocolName() 方法很普通的实现:
清单 2. getProtocolName() 方法
2 return PROTOCOL_NAME;
3 }
4
清单 3 中的代码是 isProtocolSupported() 方法很简短的实现:
清单 3. isProtocolSupported() 方法
2 return isClickMeter(address, DEFAULT_PORT, DEFAULT_RETRY, DEFAULT_TIMEOUT);
3 }
4
在 isProtocolSupported() 方法的长版本中,我们处理传入的参数以用于构造访问远程 JMX 代理的 URL。一旦从这些参数中获得了 IP 和端口,则 isProtocolSupported() 调用 isClickMeter() 方法以确定该节点上的 ClickMeter 是否处于活动状态。清单 4 显示了 isClickMeter() 代码。注意:为 URL 而定义的两个常量对应于用于 ClickMeter incPanelValue 操作所需的 HTTP 协议适配器访问 URL。
清单 4. isClickMeter() 方法
2 "/InvokeAction//MBean:name=ClickMeter/action=incPanelValue?
3 action=incPanelValue";
4 private final static String CLICK_METER_ID = "incPanelValue Successful";
5 private boolean isClickMeter(InetAddress host, int port,
6 int retries, int timeout) {
7 Category log = ThreadCategory.getInstance(getClass());
8 boolean foundClickMeter = false;
9 for (int attempts=0; attempts <= retries && !foundClickMeter;
10 attempts++)
11 {
12 URL jmxLink = null;
13 InputStream iStream = null;
14 try {
15 String hostIP = host.getHostAddress();
16 jmxLink = new URL("http", hostIP, port,
17 CLICK_METER_BEAN_LOCATOR_URL);
18 if (scanURL(jmxLink, CLICK_METER_ID, log)) {
19 foundClickMeter = true;
20 break; // get out of the for loop
21 }
22 }
23 catch(IOException e) {
24 log.info("ClickMeterPlugin: Error communicating
25 with host " + host.getHostAddress(), e);
26 foundClickMeter = false;
27 }
28 }
29 return foundClickMeter;
30 }
31
清单 5 中所显示的 scanURL() 方法是一个助手方法,它可接受作为参数的 URL 和字符串。然后,访问这个 URL,并在产生的页面中搜索所指定的字符串。如果找到该字符串,则返回 true。否则,返回 false。在这里,在访问用于 ClickMeter 的 incPanelValue 操作的 URL 之后,查寻 incPanelValue Successful字符串。
清单 5. scanURL() 方法
2 InputStream iStream = null;
3 try {
4 iStream = inURL.openStream();
5 BufferedReader urlReader =
6 new BufferedReader(new InputStreamReader(iStream));
7
8 String curLine = urlReader.readLine();
9 do {
10 if (curLine.indexOf(toSearch) != -1) {
11 return true;
12 }
13 curLine = urlReader.readLine();
14 } while (curLine != null);
15
16 }
17 catch (IOException e) {
18 e.fillInStackTrace();
19 log.debug("ClickMeterMonitor.poll:
20 Error reading from URL:"
21 + inURL, e);
22
23 }
24 finally {
25 try {
26 if(iStream != null)
27 iStream.close();
28 }
29 catch(IOException e) {
30 e.fillInStackTrace();
31 log.debug("ClickMeterMonitor.poll:
32 Error closing stream to URL.", e);
33 }
34 }
35 return false;
36 }
37 }
38
集成该插件所需的第 2 步将编辑
清单 6. protocol-plugin 定义
2 protocol="CLICKMETER"
3 class-name="org.opennms.netmgt.capsd.ClickMeterPlugin"
4 scan="on" >
5 <property key="port" value="8082"/>
6 <property key="timeout" value="2000"/>
7 <property key="retry" value="1"/>
8 </protocol-plugin>
9
您可能还希望编辑 discovery-configuration.xml 文件以限制 OpenNMS 扫描受管节点的 IP 范围。在清单 7 中,我们将其限制为两个节点,这样可以快速地找到 ClickMeter 应用程序:
清单 7. 限制发现的范围
2 <begin>192.168.23.75</begin>
3 <end>192.168.23.76</end>
4 </include-range>
5
用于 OpenNMS 的 ClickMeterMonitor
接下来,创建轮询器守护程序( pollerd )监控程序插件: org.opennms.netmgt.poller.ClickMeterMonitor 类。该类必须实现 org.opennms.netmgt.poller.ServiceMonitor 接口。OpenNMS 提供了一个基类( org.opennms.netmgt.poller.IPv4Monitor ),这个接口中的所有方法都有缺省实现。因为不需要任何特殊的初始化或资源释放,所以只需要覆盖 poll() 方法,如清单 8 所示:
清单 8. poll() 方法
2 if(iface.getType() != NetworkInterface.TYPE_IPV4)
3 throw new NetworkInterfaceNotSupportedException("Unsupported
4 interface type, only TYPE_IPV4 currently supported");
5 Category log = ThreadCategory.getInstance(getClass());
6 int retry =
7 getKeyedInteger(parameters, "retry", DEFAULT_RETRY);
8 int port =
9 getKeyedInteger(parameters, "port", DEFAULT_PORT);
10 int timeout =
11 getKeyedInteger(parameters, "timeout", DEFAULT_TIMEOUT);
12 InetAddress ipv4Addr = (InetAddress)iface.getAddress();
13 String hostIP = ipv4Addr.getHostAddress();
14 if (log.isDebugEnabled())
15 log.debug("ClickMeterMonitor.poll: Polling interface: "
16 + hostIP + " timeout: " + timeout + " retry: " + retry);
17
18 int serviceStatus = ServiceMonitor.SERVICE_UNAVAILABLE;
19 for (int attempts=0; attempts <= retry && serviceStatus !=
20 ServiceMonitor.SERVICE_AVAILABLE; attempts++) {
21 URL jmxLink = null;
22 InputStream iStream = null;
23 try {
24 jmxLink = new URL("http", hostIP, port,
25 CLICK_METER_BEAN_LOCATOR_URL);
26 if (scanURL(jmxLink, CLICK_METER_ID, log)) {
27 serviceStatus = ServiceMonitor.SERVICE_AVAILABLE;
28 break; }
29 }
30 catch(IOException e) {
31 e.fillInStackTrace();
32 log.debug("ClickMeterMonitor.poll:
33 IOException while polling address: "
34 + ipv4Addr, e);
35 }
36 } // of for
37 return serviceStatus;
38 }
39
注意清单 8 中访问 ClickMeter MBean 的 scanURL() 助手方法的用法。
在
清单 9. 轮询器守护程序 service 定义
2 user-defined="false" status="on">
3 <parameter key="timeout" value="3000"/>
4 <parameter key="port" value="8082"/>
5 </service>
6
在同一个 poller-configuration.xml 文件中,我们还应该插入 monitor 定义,如清单 10 所示:
清单 10.轮询器守护程序监控程序定义
2 class-name="org.opennms.netmgt.poller.ClickMeterMonitor" />
3