/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2006-2011 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/
package org.opennms.protocols.nsclient.capsd;
import java.net.InetAddress;
import java.util.Map;
import org.opennms.core.utils.InetAddressUtils;
import org.opennms.core.utils.ParameterMap;
import org.opennms.core.utils.ThreadCategory;
import org.opennms.netmgt.capsd.AbstractPlugin;
import org.opennms.protocols.nsclient.NSClientAgentConfig;
import org.opennms.protocols.nsclient.NsclientCheckParams;
import org.opennms.protocols.nsclient.NsclientException;
import org.opennms.protocols.nsclient.NsclientManager;
import org.opennms.protocols.nsclient.NsclientPacket;
/**
* <P>
* This class is designed to be used by the capabilities daemon to test
* whether a NSClient service is running on the remote server and if the given
* command can be successfully executed against the service.
* </P>
*
* @author <a href="mailto:matt.raykowski@gmail.com">Matt Raykowski</a>
* @author <a href="http://www.opennms.org">OpenNMS</a>
*/
public class NsclientPlugin extends AbstractPlugin {
/**
* The protocol supported by the plugin
*/
private final static String PROTOCOL_NAME = "NSCLIENT";
/**
* Default number of retries for TCP requests.
*/
private final static int DEFAULT_RETRY = 0;
/**
* Default timeout (in milliseconds) for TCP requests.
*/
private final static int DEFAULT_TIMEOUT = 5000;
/**
* 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() {
return PROTOCOL_NAME;
}
/**
* {@inheritDoc}
*
* Returns true if the protocol defined by this plugin is supported. If
* the protocol is not supported then a false value is returned to the
* caller.
* <P>
* The NsclientPlugin does not support undirected checks, we must have a
* map of parameters to determine how to issue a check to the target
* server.
*/
public boolean isProtocolSupported(InetAddress address) {
throw new UnsupportedOperationException(
"Undirected TCP checking not "
+ "supported");
}
/**
* {@inheritDoc}
*
* Returns true if the protocol defined by this plugin is supported. If
* the protocol is not supported then a false value is returned to the
* 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.
* <P>
* The following parameters are used by this plugin:
* <UL>
* <LI>command - the command to be executed on this node.
* <LI>port - used to override the default NSClient port.
* <LI>password - used to override the default NSClient password
* <LI>retry - overrides the number of times to retry connecting to the
* service.
* <LI>timeout - tcp port timeout.
* <LI>parameter - a string used for checking services. see documentation
* on specific check types for use.
* <LI>criticalPercent - typically a percentage used for testing results,
* for example disk space used.
* <LI>warningPercent - typically a percentage used for testing results,
* for example memory space used.
* </UL>
* Protocol will return as supported only if the result code is
* <code>NsclientPacket.RES_STATE_OK</code> or
* <code>NsclientPacket.RES_STATE_WARNING</code>.
*/
public boolean isProtocolSupported(InetAddress address, Map<String, Object> qualifiers) {
int retries = DEFAULT_RETRY;
int timeout = DEFAULT_TIMEOUT;
int port = NsclientManager.DEFAULT_PORT;
String password = NSClientAgentConfig.DEFAULT_PASSWORD;
String parameter = null;
String command = null;
int critPerc = 0, warnPerc = 0;
if (qualifiers != null) {
command = ParameterMap.getKeyedString(
qualifiers,
"command",
NsclientManager.convertTypeToString(NsclientManager.CHECK_CLIENTVERSION));
port = ParameterMap.getKeyedInteger(qualifiers, "port",
NsclientManager.DEFAULT_PORT);
retries = ParameterMap.getKeyedInteger(qualifiers, "retry",
DEFAULT_RETRY);
timeout = ParameterMap.getKeyedInteger(qualifiers, "timeout",
DEFAULT_TIMEOUT);
parameter = ParameterMap.getKeyedString(qualifiers, "parameter",
null);
critPerc = ParameterMap.getKeyedInteger(qualifiers,
"criticalPercent", 0);
warnPerc = ParameterMap.getKeyedInteger(qualifiers,
"warningPercent", 0);
password = ParameterMap.getKeyedString(qualifiers, "password",
NSClientAgentConfig.DEFAULT_PASSWORD);
}
// set up my check params.
NsclientCheckParams params = new NsclientCheckParams(critPerc,
warnPerc,
parameter);
// and perform the check, we'll get a packet back containing the check
// data.
NsclientPacket pack = isServer(address, port, password, command, retries,
timeout, params);
if (pack == null) {
log().debug("Received a null packet response from isServer.");
return false;
}
// only fail on critical and unknown returns .
if (pack.getResultCode() != NsclientPacket.RES_STATE_CRIT
&& pack.getResultCode() != NsclientPacket.RES_STATE_UNKNOWN) {
return true;
} else {
return false;
}
}
/**
* <P>
* Test to see if the paassed host-port pair is an endpoint for a TCP
* server. If there is a TCP server at the destination value then a
* connection is made using the params variable data and a check is
* requested from the remote NSClient service.
* </P>
*
* @param host
* The remote host to connect to.
* @param port
* The remote port on the host.
* @param command
* The command to execute on the remote server.
* @param retries
* The number of retries to attempt when connecting.
* @param timeout
* The TCP socket timeout to use.
* @param params
* The NSClient parameters used to validate the response.
* @return The NsclientPacket the server sent, updated by NsclientManager
* to contain the proper result code based on the params passed.
*/
private NsclientPacket isServer(InetAddress host, int port,
String password, String command, int retries, int timeout,
NsclientCheckParams params) {
boolean isAServer = false;
NsclientPacket response = null;
for (int attempts = 0; attempts <= retries && !isAServer; attempts++) {
try {
NsclientManager client = new NsclientManager(InetAddressUtils.str(host), port, password);
client.setTimeout(timeout);
client.init();
response = client.processCheckCommand(NsclientManager.convertStringToType(command), params);
log().debug("NsclientPlugin: " + command + ": " + response.getResponse());
isAServer = true;
} catch (NsclientException e) {
StringBuffer message = new StringBuffer();
message.append("NsclientPlugin: Check failed... NsclientManager returned exception: ");
message.append(e.getMessage());
message.append(" : ");
message.append((e.getCause() == null ? "": e.getCause().getMessage()));
log().info(message.toString());
isAServer = false;
}
}
return response;
}
private ThreadCategory log() {
return ThreadCategory.getInstance(getClass());
}
}