/*
|
* CDDL HEADER START
|
*
|
* The contents of this file are subject to the terms of the
|
* Common Development and Distribution License, Version 1.0 only
|
* (the "License"). You may not use this file except in compliance
|
* with the License.
|
*
|
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
|
* or http://forgerock.org/license/CDDLv1.0.html.
|
* See the License for the specific language governing permissions
|
* and limitations under the License.
|
*
|
* When distributing Covered Code, include this CDDL HEADER in each
|
* file and include the License file at legal-notices/CDDLv1_0.txt.
|
* If applicable, add the following below this CDDL HEADER, with the
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
* information:
|
* Portions Copyright [yyyy] [name of copyright owner]
|
*
|
* CDDL HEADER END
|
*
|
*
|
* Copyright 2008 Sun Microsystems, Inc.
|
* Portions Copyright 2012-2014 ForgeRock Inc.
|
*/
|
package org.opends.server.snmp;
|
|
import java.security.PrivilegedAction;
|
import java.util.HashSet;
|
import java.util.Iterator;
|
import java.util.Set;
|
|
import javax.management.Attribute;
|
import javax.management.MBeanServer;
|
import javax.management.ObjectName;
|
import javax.security.auth.Subject;
|
|
import org.forgerock.i18n.slf4j.LocalizedLogger;
|
import org.opends.server.protocols.internal.InternalClientConnection;
|
import org.opends.server.protocols.jmx.Credential;
|
import org.opends.server.protocols.jmx.OpendsJmxPrincipal;
|
|
import com.sun.management.snmp.SnmpStatusException;
|
|
/**
|
* The SNMPMonitor Class allows to get a singleton SNMPMonitor object allowing
|
* to access the JMX cn=monitor MBean.
|
*/
|
public class SNMPMonitor
|
{
|
|
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
|
|
/**
|
* Singleton SNMPMonitor object.
|
*/
|
private static SNMPMonitor monitor = null;
|
/**
|
* Monitor MBeanServer server.
|
*/
|
private MBeanServer server;
|
/**
|
* Subject Auth to use to access the JMX Mbeans cn=monitor.
|
*/
|
private Subject subject = null;
|
/**
|
* Pattern to use to query the cn=monitor MBeans.
|
*/
|
public static ObjectName pattern;
|
|
static
|
{
|
try
|
{
|
pattern =
|
new ObjectName(SNMPConnectionHandlerDefinitions.JMX_DOMAIN
|
+ "Name=rootDSE,Rdn1=cn-monitor,*");
|
}
|
catch (Exception ex)
|
{
|
logger.traceException(ex);
|
}
|
}
|
|
/**
|
* Creates an SNMPMonitor object mapping.
|
*
|
* @param server
|
* to use to the mapping
|
*/
|
private SNMPMonitor(MBeanServer server)
|
{
|
this.server = server;
|
this.subject = new Subject();
|
this.subject.getPrincipals().add(new OpendsJmxPrincipal("cn=anonymous"));
|
InternalClientConnection clientConnection =
|
InternalClientConnection.getRootConnection();
|
this.subject.getPrivateCredentials().add(new Credential(clientConnection));
|
}
|
|
/**
|
* Gets the singleton SNMPMonitor object.
|
*
|
* @param server
|
* The server
|
* @return the SNMPMonitor mapping object.
|
*/
|
public static SNMPMonitor getMonitor(MBeanServer server)
|
{
|
if (monitor == null)
|
{
|
monitor = new SNMPMonitor(server);
|
}
|
return monitor;
|
}
|
|
/**
|
* Gets the Connection Handlers Statistics MBean.
|
*
|
* @return the Set of Connection Handlers Statistics. If Statistics do not
|
* exist then an empty Set is returned
|
*/
|
public Set<ObjectName> getConnectionHandlersStatistics()
|
{
|
Set<ObjectName> results = new HashSet<ObjectName>();
|
try
|
{
|
Set monitorObjects = this.server.queryNames(SNMPMonitor.pattern, null);
|
for (Iterator iter = monitorObjects.iterator(); iter.hasNext();)
|
{
|
ObjectName name = (ObjectName) iter.next();
|
if ((name.getCanonicalName().contains("Connection_Handler"))
|
&& (name.getCanonicalName().endsWith("_Statistics")))
|
{
|
results.add(name);
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
logger.traceException(ex);
|
}
|
return results;
|
}
|
|
/**
|
* Return the ObjectName of the Connection Handler corresponding to the
|
* statistics name.
|
*
|
* @param statistics
|
* ObjectName
|
* @return the Connection Handler ObjectName, null otherwise
|
*/
|
public ObjectName getConnectionHandler(ObjectName statistics)
|
{
|
|
// Check parameter
|
if (statistics == null)
|
{
|
return null;
|
}
|
|
try
|
{
|
String value = statistics.getCanonicalName();
|
if (!value.endsWith("_Statistics"))
|
{
|
return null;
|
}
|
int index = value.indexOf("_Statistics");
|
String name = value.substring(0, index);
|
ObjectName connectionHandlerName = new ObjectName(name);
|
|
// Check if the MBean exists
|
Set query = this.server.queryNames(connectionHandlerName, null);
|
if ((query != null) && (!query.isEmpty()))
|
{
|
return connectionHandlerName;
|
}
|
}
|
catch (Exception ex)
|
{
|
logger.traceException(ex);
|
}
|
return null;
|
}
|
|
/**
|
* Return a Set of Connection Handler ObjectNames.
|
*
|
* @return the Set of ObjectNames, an empty Set if no connection handlers
|
*/
|
public Set<ObjectName> getConnectionHandlers()
|
{
|
Set monitorObjects;
|
Set<ObjectName> results = new HashSet<ObjectName>();
|
try
|
{
|
monitorObjects = this.server.queryNames(SNMPMonitor.pattern, null);
|
for (Iterator iter = monitorObjects.iterator(); iter.hasNext();)
|
{
|
ObjectName name = (ObjectName) iter.next();
|
if ((name.getCanonicalName().contains("Connection_Handler"))
|
&& (!(name.getCanonicalName().endsWith("_Statistics")))
|
&& (name.getKeyProperty("Rdn3") == null))
|
{
|
results.add(name);
|
}
|
}
|
return results;
|
}
|
catch (Exception ex)
|
{
|
logger.traceException(ex);
|
}
|
return results;
|
}
|
|
/**
|
* Returns the ObjectName of the Statistics Connection Handler name.
|
* corresponding to the Connection Handler name
|
*
|
* @param connectionHandlerName
|
* The connection handler name
|
* @return the ObjectName of the statistics ObjectName, null if the statistics
|
* could not be found
|
*/
|
public ObjectName getConnectionHandlerStatistics(
|
ObjectName connectionHandlerName)
|
{
|
|
if (connectionHandlerName == null)
|
{
|
return null;
|
}
|
try
|
{
|
String value =
|
connectionHandlerName.getCanonicalName().concat("_Statistics");
|
ObjectName statistics = new ObjectName(value);
|
// Check if the MBean exists
|
Set query = this.server.queryNames(statistics, null);
|
if ((query != null) && (!query.isEmpty()))
|
{
|
return statistics;
|
}
|
}
|
catch (Exception ex)
|
{
|
logger.traceException(ex);
|
}
|
return null;
|
}
|
|
/**
|
* Get the value of the attribute.
|
*
|
* @param name
|
* of Mbean as a String
|
* @param attribute
|
* to look for
|
* @return the value of the attribute, null if the attribute could not be
|
* found
|
*/
|
public Object getAttribute(String name, String attribute)
|
{
|
try
|
{
|
ObjectName objName =
|
new ObjectName(SNMPConnectionHandlerDefinitions.JMX_DOMAIN + "Name="
|
+ name);
|
return getAttribute(objName, attribute);
|
}
|
catch (Exception ex)
|
{
|
logger.traceException(ex);
|
}
|
return null;
|
}
|
|
/**
|
* Gets the value of an attribute.
|
*
|
* @param name
|
* of the Mbean
|
* @param attribute
|
* to look for
|
* @return the value of the attribute, null if the attribute value could not
|
* be found
|
*/
|
@SuppressWarnings("unchecked")
|
public Object getAttribute(final ObjectName name, final String attribute)
|
{
|
return Subject.doAs(this.subject, new PrivilegedAction()
|
{
|
|
public Object run()
|
{
|
try
|
{
|
Attribute attr = (Attribute) server.getAttribute(name, attribute);
|
if (attr != null)
|
{
|
return attr.getValue();
|
}
|
}
|
catch (Exception ex)
|
{
|
logger.traceException(ex);
|
}
|
return null;
|
}
|
});
|
}
|
|
/**
|
* Wrapper for SNMP Byte[].
|
*
|
* @param s
|
* value string
|
* @return a Byte[]
|
*/
|
public static Byte[] string2ByteArray(String s)
|
{
|
byte[] b = s.getBytes();
|
Byte[] barray = new Byte[b.length];
|
for (int index = 0; index < b.length; index++)
|
{
|
barray[index] = new Byte(b[index]);
|
}
|
return barray;
|
}
|
|
/**
|
* Wrapper for SNMP Counter32.
|
*
|
* @param v
|
* value
|
* @return a counter32
|
*/
|
public static long counter32Value(long v)
|
{
|
if (v > (pow(2, 32) - 1))
|
{
|
return (v % pow(2, 32));
|
}
|
else
|
{
|
return v;
|
}
|
}
|
|
/**
|
* Wrapper for SNMP Counter32.
|
*
|
* @param V
|
* Value
|
* @return a Counter32
|
*/
|
public static Long counter32Value(Long V)
|
{
|
long v = V.longValue();
|
if (v > (pow(2, 32) - 1))
|
{
|
return new Long(v % pow(2, 32));
|
}
|
else
|
{
|
return V;
|
}
|
}
|
|
/**
|
* Latcher for SNMP Gauge32.
|
*
|
* @param v
|
* value
|
* @return a gauge32
|
*/
|
public static long gauge32Value(long v)
|
{
|
if (v > (pow(2, 32) - 1))
|
{
|
return (pow(2, 32) - 1);
|
}
|
else
|
{
|
return v;
|
}
|
}
|
|
/**
|
* Latcher for SNMP Gauge32.
|
*
|
* @param V
|
* value
|
* @return a gauge32
|
*/
|
public static Long gauge32Value(Long V)
|
{
|
long v = V.longValue();
|
if (v > (pow(2, 32) - 1))
|
{
|
return new Long(pow(2, 32) - 1);
|
}
|
else
|
{
|
return V;
|
}
|
}
|
|
/**
|
* Checker for SNMP INTEGER.
|
*
|
* @param V
|
* value
|
* @return an Integer
|
* @throws com.sun.management.snmp.SnmpStatusException
|
* If an error occurs
|
*/
|
public static Integer integerValue(Long V) throws SnmpStatusException
|
{
|
long v = V.longValue();
|
if (v > (pow(2, 31) - 1))
|
{
|
throw new SnmpStatusException("Returned intrumented value size too big");
|
}
|
Integer ret = new Integer(V.intValue());
|
return ret;
|
}
|
|
/**
|
* pow x^y.
|
*/
|
private static long pow(long x, long y)
|
{
|
int j = 1;
|
long k = x;
|
if (y == 0)
|
{
|
return 1;
|
}
|
if (y == 1)
|
{
|
return x;
|
}
|
while (j < y)
|
{
|
k = k * x;
|
j++;
|
}
|
return k;
|
}
|
}
|