/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2009-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.wmi;
import java.util.ArrayList;
import org.opennms.protocols.wmi.wbem.OnmsWbemObjectSet;
/**
* <P>
* This provides an easy abtraction of the WmiClient functionality. It allows
* programmers to make simple WMI Class + WMI Object queries and then measure
* the resulting values against parameters.
*
* The purpose of the WMI Manager is to provide poller-style functionality where
* low-level access to WBEM objects and methods is not essential.
* </P>
*
* @author <a href="mailto:matt.raykowski@gmail.com">Matt Raykowski</a>
* @author <a href="http://www.opennms.org">OpenNMS</a>
*/
public class WmiManager {
/**
* The default socket timeout.
*/
public static int DEFAULT_SOCKET_TIMEOUT = 5000;
/**
* Stores the host name the manager is connect(ing/ed) to.
*/
private String m_HostName = null;
/**
* The domain to use when requesting a check.
*/
private String m_Domain = null;
/**
* The username to use when requesting a check.
*/
private String m_Username = null;
/**
* The password to use when requesting a check.
*/
private String m_Password = null;
private IWmiClient m_WmiClient = null;
private String m_MatchType = null;
private int m_Timeout = DEFAULT_SOCKET_TIMEOUT;
/**
* This method is used for setting the password used to perform service
* checks.
*
* @param pass
* the password to use when performing service checks.
*/
public void setPassword(final String pass) {
m_Password = pass;
}
/**
* This method is used to set the host name to connect to for performing
* remote service checks. This method must be called before calling the
* init() method or it will have no effect.
*
* @param host
* the host name to connect to.
* @see init
*/
public void setHostName(final String host) {
m_HostName = host;
}
/**
* Returns the host name being used to connect to the remote service.
*
* @return the host name being used to connect to the remote service.
*/
public String getHostName() {
return m_HostName;
}
/**
* This method is used to set the TCP socket timeout to be used when
* connecting to the remote service. This must be called before calling
* <code>init</code> or it will have no effect.
*
* @param timeout
* the TCP socket timeout.
*/
public void setTimeout(final int timeout) {
m_Timeout = timeout;
}
/**
* Returns the TCP socket timeout used when connecting to the remote
* service.
*
* @return the tcp socket timeout.
*/
public int getTimeout() {
return m_Timeout;
}
/**
* Constructor.
*
* @param host
* sets the host name to connect to.
* @param user
* sets the username to connect with
* @param pass
* sets the password to connect with.
*/
public WmiManager(final String host, final String user, final String pass) {
m_HostName = host;
m_Username = user;
m_Password = pass;
m_Domain = host;
m_MatchType = "all";
}
/**
* Constructor.
*
* @param host
* sets the host name to connect to.
* @param user
* sets the username to connect with
* @param pass
* sets the password to connect with.
* @param domain
* sets the domain to connect to.
*/
public WmiManager(final String host, final String user, final String pass, final String domain) {
m_HostName = host;
m_Username = user;
m_Password = pass;
m_MatchType = "all";
if ("".equals(domain)) {
m_Domain = host;
} else {
m_Domain = domain;
}
}
/**
* Constructor.
*
* @param host
* sets the host name to connect to.
* @param user
* sets the username to connect with
* @param pass
* sets the password to connect with.
* @param domain
* sets the domain to connect to.
* @param matchType
* the type of matching to be used for multiple results: all, none, some, one.
*/
public WmiManager(final String host, final String user, final String pass, final String domain, final String matchType) {
m_HostName = host;
m_Username = user;
m_Password = pass;
if (isValidMatchType(matchType)) {
m_MatchType = matchType;
} else {
m_MatchType = "all";
}
if (domain == null || "".equals(domain)) {
m_Domain = host;
} else {
m_Domain = domain;
}
}
/**
* Constructor. Made private to prevent construction without parameters.
*/
@SuppressWarnings("unused")
private WmiManager() {
// nothing to do, don't allow it.
}
/**
* <p>isValidMatchType</p>
*
* @param matchType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isValidMatchType(final String matchType) {
if (matchType.equals("all") || matchType.equals("none") || matchType.equals("some") || matchType.equals("one")) {
return true;
}
return false;
}
/**
* <p>isValidOpType</p>
*
* @param opType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isValidOpType(final String opType) {
try {
WmiMgrOperation.valueOf(opType);
return true;
} catch(IllegalArgumentException e) {
return false;
}
}
/**
* This creates a new WmiClient and creates a connection to the host.
*
* @throws org.opennms.protocols.wmi.WmiException
* An exception will be thrown if the system is unable to look
* up the host and if J-Interop throws an exception this will
* re-throw that exception so that implementors need not know
* J-Interop exceptions.
*/
public void init() throws WmiException {
m_WmiClient = (IWmiClient)new WmiClient(m_HostName);
m_WmiClient.connect(m_Domain, m_Username, m_Password);
}
/**
* This is for tests to harness and create a mock client. Do not use!
*
* @param client allows a IWmiClient to be pre-instantiated. Used for mock testing.
* @throws org.opennms.protocols.wmi.WmiException is thrown if there are any problems connecting.
*/
public void init(final IWmiClient client) throws WmiException {
m_WmiClient = client;
m_WmiClient.connect(m_Domain, m_Username, m_Password);
}
/**
* <p>close</p>
*
* @throws org.opennms.protocols.wmi.WmiException if any.
*/
public void close() throws WmiException {
if(m_WmiClient == null)
{
throw new WmiException("Failed to close client: WmiClient was not initialized.");
}
m_WmiClient.disconnect();
}
/**
* <p>performOp</p>
*
* @param params a {@link org.opennms.protocols.wmi.WmiParams} object.
* @return a {@link org.opennms.protocols.wmi.WmiResult} object.
* @throws org.opennms.protocols.wmi.WmiException if any.
*/
public WmiResult performOp(final WmiParams params) throws WmiException {
// If we defined a WQL query string, exec the query.
if( params.getWmiOperation().equals(WmiParams.WMI_OPERATION_WQL)) {
return performExecQuery(params);
} else {
// Otherwise perform an InstanceOf.
return performInstanceOf(params);
}
}
/**
* <p>performExecQuery</p>
*
* @param params a {@link org.opennms.protocols.wmi.WmiParams} object.
* @return a {@link org.opennms.protocols.wmi.WmiResult} object.
* @throws org.opennms.protocols.wmi.WmiException if any.
*/
public WmiResult performExecQuery(final WmiParams params) throws WmiException {
final ArrayList<Object> wmiObjects = new ArrayList<Object>();
final OnmsWbemObjectSet wos = m_WmiClient.performExecQuery(params.getWql());
for(int i=0; i<wos.count(); i++) {
wmiObjects.add(wos.get(i).getWmiProperties().getByName(params.getWmiObject()).getWmiValue());
}
final WmiResult result = new WmiResult(wmiObjects);
if (params.getCompareOperation().equals("NOOP")) {
result.setResultCode(WmiResult.RES_STATE_OK);
} else if (params.getCompareOperation().equals("EQ")
|| params.getCompareOperation().equals("NEQ")
|| params.getCompareOperation().equals("GT")
|| params.getCompareOperation().equals("LT")) {
performResultCheck(result, params);
} else {
result.setResultCode(WmiResult.RES_STATE_UNKNOWN);
}
return result;
}
/**
* <p>performInstanceOf</p>
*
* @param params a {@link org.opennms.protocols.wmi.WmiParams} object.
* @return a {@link org.opennms.protocols.wmi.WmiResult} object.
* @throws org.opennms.protocols.wmi.WmiException if any.
*/
public WmiResult performInstanceOf(final WmiParams params) throws WmiException {
final ArrayList<Object> wmiObjects = new ArrayList<Object>();
final OnmsWbemObjectSet wos = m_WmiClient.performInstanceOf(params.getWmiClass());
for(int i=0; i<wos.count(); i++) {
wmiObjects.add(wos.get(i).getWmiProperties().getByName(params.getWmiObject()).getWmiValue());
}
final WmiResult result = new WmiResult(wmiObjects);
if (params.getCompareOperation().equals("NOOP")) {
result.setResultCode(WmiResult.RES_STATE_OK);
} else if (params.getCompareOperation().equals("EQ")
|| params.getCompareOperation().equals("NEQ")
|| params.getCompareOperation().equals("GT")
|| params.getCompareOperation().equals("LT")) {
performResultCheck(result, params);
} else {
result.setResultCode(WmiResult.RES_STATE_UNKNOWN);
}
return result;
}
private void performResultCheck(final WmiResult wmiResult, final WmiParams params) throws WmiException {
final ArrayList<Object> wmiObjects = wmiResult.getResponse();
int matches = 0;
final int total = wmiObjects.size();
for (int i = 0; i < total; i++) {
final Object wmiObj = wmiObjects.get(i);
final WmiMgrOperation op = WmiMgrOperation.valueOf(params.getCompareOperation());
if(op.compareString(wmiObj, (String)params.getCompareValue())) {
matches++;
}
}
/*
* Check that we meet the match requirements:
* - all: all objects must match, one or more.
* - none: no objects must match
* - one: only one object must match
* - some: one or more objects but not all objects must match.
*/
if (m_MatchType.equals("all") && matches == total && matches > 0) {
wmiResult.setResultCode(WmiResult.RES_STATE_OK);
} else if (m_MatchType.equals("none") && matches == 0) {
wmiResult.setResultCode(WmiResult.RES_STATE_OK);
} else if (m_MatchType.equals("one") && matches == 1) {
wmiResult.setResultCode(WmiResult.RES_STATE_OK);
} else if (m_MatchType.equals("some") && matches >= 1) {
// we want to match more than one but not all.
if (matches != total) {
wmiResult.setResultCode(WmiResult.RES_STATE_OK);
} else {
wmiResult.setResultCode(WmiResult.RES_STATE_CRIT);
}
} else {
wmiResult.setResultCode(WmiResult.RES_STATE_CRIT);
}
}
/**
* <p>getMatchType</p>
*
* @return the m_MatchType
*/
public String getMatchType() {
return m_MatchType;
}
/**
* <p>setMatchType</p>
*
* @param matchType the m_MatchType to set
*/
public void setMatchType(final String matchType) {
m_MatchType = matchType;
}
}