/*
* 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
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* 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
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 ForgeRock Inc.
*/
package org.opends.server.snmp;
import com.sun.management.snmp.SnmpStatusException;
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.opends.server.loggers.debug.DebugLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.jmx.Credential;
import org.opends.server.protocols.jmx.OpendsJmxPrincipal;
import org.opends.server.types.DebugLogLevel;
/**
* The SNMPMonitor Class allows to get a singleton SNMPMonitor object allowing
* to access the JMX cn=monitor MBean.
*/
public class SNMPMonitor {
/**
* Debug Tracer for this class.
*/
private static final DebugTracer TRACER = DebugLogger.getTracer();
/**
* 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) {
if (DebugLogger.debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, 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) {
if (DebugLogger.debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, 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) {
if (DebugLogger.debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, 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) {
if (DebugLogger.debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, 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) {
if (DebugLogger.debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, 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) {
if (DebugLogger.debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, 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) {
if (DebugLogger.debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, 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;
}
}