/******************************************************************************* * 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.net.UnknownHostException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.logging.Level; import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.common.JISystem; import org.jinterop.dcom.core.IJIComObject; import org.jinterop.dcom.core.JIComServer; import org.jinterop.dcom.core.JIProgId; import org.jinterop.dcom.core.JISession; import org.jinterop.dcom.core.JIString; import org.jinterop.dcom.core.JIVariant; import org.jinterop.dcom.impls.JIObjectFactory; import org.jinterop.dcom.impls.automation.IJIDispatch; import org.opennms.core.utils.LogUtils; import org.opennms.protocols.wmi.wbem.OnmsWbemFlagReturnEnum; import org.opennms.protocols.wmi.wbem.OnmsWbemObject; import org.opennms.protocols.wmi.wbem.OnmsWbemObjectSet; import org.opennms.protocols.wmi.wbem.jinterop.OnmsWbemObjectImpl; import org.opennms.protocols.wmi.wbem.jinterop.OnmsWbemObjectSetImpl; /** * <P> * This is a low-level WMI client harnessing DCOM to communicate with remote agents. * The interface provided is similar but not identical to that of the SWbemServices * interface. * </P> * * @author <a href="mailto:matt.raykowski@gmail.com">Matt Raykowski</a> * @author <a href="http://www.opennms.org">OpenNMS</a> */ public class WmiClient implements IWmiClient { private JIComServer m_ComStub = null; private IJIComObject m_ComObject = null; private IJIDispatch m_Dispatch = null; private String m_Address = null; private JISession m_Session = null; private IJIDispatch m_WbemServices = null; private static final String WMI_CLSID = "76A6415B-CB41-11d1-8B02-00600806D9B6"; private static final String WMI_PROGID = "WbemScripting.SWbemLocator"; /** * <p>Constructor for WmiClient.</p> * * @param address a {@link java.lang.String} object. * @throws org.opennms.protocols.wmi.WmiException if any. */ public WmiClient(final String address) throws WmiException { JISystem.setAutoRegisteration(true); JISystem.getLogger().setLevel(Level.OFF); m_Address = address; } /** {@inheritDoc} */ public OnmsWbemObjectSet performInstanceOf(final String wmiClass) throws WmiException { try { // Execute the InstancesOf method on the remote SWbemServices object. final JIVariant results[] = m_WbemServices.callMethodA("InstancesOf", new Object[]{new JIString(wmiClass), 0, JIVariant.OPTIONAL_PARAM()}); final IJIDispatch wOSd = (IJIDispatch) JIObjectFactory.narrowObject((results[0]).getObjectAsComObject()); return new OnmsWbemObjectSetImpl(wOSd); } catch (final JIException e) { throw new WmiException("Failed to perform WMI operation (\\\\" + wmiClass + ") : " + e.getMessage(), e); } } /** {@inheritDoc} */ public OnmsWbemObjectSet performExecQuery(final String strQuery) throws WmiException { return performExecQuery(strQuery, "WQL", OnmsWbemFlagReturnEnum.wbemFlagReturnImmediately.getReturnFlagValue()); } /** {@inheritDoc} */ public OnmsWbemObjectSet performExecQuery (final String strQuery, final String strQueryLanguage, final Integer flags) throws WmiException { try { final JIVariant results[] = m_WbemServices.callMethodA("ExecQuery", new Object[]{new JIString(strQuery), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(),JIVariant.OPTIONAL_PARAM()}); final IJIDispatch wOSd = (IJIDispatch)JIObjectFactory.narrowObject((results[0]).getObjectAsComObject()); return new OnmsWbemObjectSetImpl(wOSd); } catch(final JIException e) { throw new WmiException("Failed to execute query '" + strQuery + "': " + e.getMessage(), e); } } /** * <p>performWmiGet</p> * * @param strObjectPath a {@link java.lang.String} object. * @return a {@link org.opennms.protocols.wmi.wbem.OnmsWbemObject} object. * @throws org.opennms.protocols.wmi.WmiException if any. */ public OnmsWbemObject performWmiGet(final String strObjectPath) throws WmiException { try { final JIVariant results[] = m_WbemServices.callMethodA("Get", new Object[]{new JIString(strObjectPath), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM()}); final IJIDispatch obj_dsp = (IJIDispatch) JIObjectFactory.narrowObject((results[0]).getObjectAsComObject()); return new OnmsWbemObjectImpl(obj_dsp); } catch (final JIException e) { throw new WmiException("Failed to perform get '" + strObjectPath + "': " + e.getMessage(), e); } } /** * <p>performSubclassOf</p> * * @param strSuperClass a {@link java.lang.String} object. * @return a {@link org.opennms.protocols.wmi.wbem.OnmsWbemObjectSet} object. * @throws org.opennms.protocols.wmi.WmiException if any. */ public OnmsWbemObjectSet performSubclassOf(final String strSuperClass) throws WmiException { try { final JIVariant results[] = m_WbemServices.callMethodA("SubclassesOf", new Object[]{new JIString(strSuperClass), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM()}); final IJIDispatch objset_dsp = (IJIDispatch) JIObjectFactory.narrowObject((results[0]).getObjectAsComObject()); return new OnmsWbemObjectSetImpl(objset_dsp); } catch (final JIException e) { throw new WmiException("Failed to perform SubclassesOf '" + strSuperClass + "': " + e.getMessage(), e); } } /** * <p>performSubclassOf</p> * * @return a {@link org.opennms.protocols.wmi.wbem.OnmsWbemObjectSet} object. * @throws org.opennms.protocols.wmi.WmiException if any. */ public OnmsWbemObjectSet performSubclassOf() throws WmiException { try { final JIVariant results[] = m_WbemServices.callMethodA("SubclassesOf", new Object[]{ JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM()}); final IJIDispatch objset_dsp = (IJIDispatch) JIObjectFactory.narrowObject((results[0]).getObjectAsComObject()); return new OnmsWbemObjectSetImpl(objset_dsp); } catch (final JIException e) { throw new WmiException("Failed to perform SubclassesOf: " + e.getMessage(), e); } } /** * <p>convertToNativeType</p> * * @param type a {@link org.jinterop.dcom.core.JIVariant} object. * @return a {@link java.lang.Object} object. * @throws org.opennms.protocols.wmi.WmiException if any. */ public static Object convertToNativeType(final JIVariant type) throws WmiException { try { if (type.isArray()) { final ArrayList<Object> objs = new ArrayList<Object>(); final Object [] array = (Object[])type.getObjectAsArray().getArrayInstance(); for (final Object element : array) { objs.add(convertToNativeType((JIVariant)element)); } return objs; } switch (type.getType()) { case JIVariant.VT_NULL: return null; case JIVariant.VT_BSTR: return type.getObjectAsString().getString(); case JIVariant.VT_I2: // sint16 return type.getObjectAsShort(); case JIVariant.VT_I4: return type.getObjectAsInt(); case JIVariant.VT_UI1: // uint8 (convert to Java Number) return type.getObjectAsUnsigned().getValue(); case JIVariant.VT_BOOL: return type.getObjectAsBoolean(); case JIVariant.VT_DECIMAL: return type.getObjectAsFloat(); case JIVariant.VT_DATE: return type.getObjectAsDate(); default: throw new WmiException("Unknown type presented (" + type.getType() + "), defaulting to Object: " + type.toString()); } } catch (final JIException e) { throw new WmiException("Failed to conver WMI type to native object: " + e.getMessage(), e); } } /** {@inheritDoc} */ public void connect(final String domain, final String username, final String password) throws WmiException { try { m_Session = JISession.createSession(domain, username, password); m_Session.useSessionSecurity(true); m_Session.setGlobalSocketTimeout(5000); m_ComStub = new JIComServer(JIProgId.valueOf(WMI_PROGID), m_Address, m_Session); final IJIComObject unknown = m_ComStub.createInstance(); m_ComObject = unknown.queryInterface(WMI_CLSID); // This will obtain the dispatch interface m_Dispatch = (IJIDispatch) JIObjectFactory.narrowObject(m_ComObject.queryInterface(IJIDispatch.IID)); final JIVariant results[] = m_Dispatch.callMethodA( "ConnectServer", new Object[]{ new JIString(m_Address), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), JIVariant.OPTIONAL_PARAM(), 0, JIVariant.OPTIONAL_PARAM() } ); m_WbemServices = (IJIDispatch) JIObjectFactory.narrowObject((results[0]).getObjectAsComObject()); } catch (final JIException e) { if (m_Session != null) { try { JISession.destroySession(m_Session); } catch (JIException e1) { LogUtils.errorf(this, e1, "Failed to destroy session after incomplete connect with host '%s'.", m_Address); } } throw new WmiException("Failed to establish COM session with host '" + m_Address + "': " + e.getMessage(), e); } catch (final UnknownHostException e) { if (m_Session != null) { try { JISession.destroySession(m_Session); } catch (JIException e1) { LogUtils.errorf(this, e1, "Failed to destroy session after unknown host '%s'.", m_Address); } } throw new WmiException("Unknown host '" + m_Address + "'. Failed to connect to WMI agent.", e); } } /** * <p>disconnect</p> * * @throws org.opennms.protocols.wmi.WmiException if any. */ public void disconnect() throws WmiException { try { JISession.destroySession(m_Session); } catch (JIException e) { throw new WmiException("Failed to destroy J-Interop session: " + e.getMessage(), e); } } /** * <p>convertWmiDate</p> * * @param dateStr a {@link java.lang.String} object. * @return a {@link java.util.Date} object. * @throws java.text.ParseException if any. */ public static Date convertWmiDate(final String dateStr) throws ParseException { return new SimpleDateFormat("yyyyMMddHHmmss.ssssss+000").parse(dateStr); } // TODO This needs to be completed. @SuppressWarnings("unused") private static boolean isNumeric(final String str) { try { Integer.parseInt(str); return true; } catch (final NumberFormatException nfe) { return false; } } // TODO this needs to be completed. @SuppressWarnings("unused") private static boolean isDate(final String str) { // Parse the date. try { DateFormat.getDateInstance().parse(str); return true; } catch (final ParseException e) { return false; } } }