1 /* 2 * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package sun.management.snmp.jvminstr; 26 27 // java imports 28 // 29 import com.sun.jmx.mbeanserver.Util; 30 import java.util.List; 31 import java.util.Map; 32 33 // jmx imports 34 // 35 import javax.management.MBeanServer; 36 import javax.management.ObjectName; 37 import com.sun.jmx.snmp.SnmpCounter; 38 import com.sun.jmx.snmp.SnmpCounter64; 39 import com.sun.jmx.snmp.SnmpGauge; 40 import com.sun.jmx.snmp.SnmpInt; 41 import com.sun.jmx.snmp.SnmpUnsignedInt; 42 import com.sun.jmx.snmp.SnmpIpAddress; 43 import com.sun.jmx.snmp.SnmpTimeticks; 44 import com.sun.jmx.snmp.SnmpOpaque; 45 import com.sun.jmx.snmp.SnmpString; 46 import com.sun.jmx.snmp.SnmpStringFixed; 47 import com.sun.jmx.snmp.SnmpOid; 48 import com.sun.jmx.snmp.SnmpNull; 49 import com.sun.jmx.snmp.SnmpValue; 50 import com.sun.jmx.snmp.SnmpVarBind; 51 import com.sun.jmx.snmp.SnmpStatusException; 52 53 // jdmk imports 54 // 55 import com.sun.jmx.snmp.agent.SnmpIndex; 56 import com.sun.jmx.snmp.agent.SnmpMib; 57 import com.sun.jmx.snmp.agent.SnmpMibTable; 58 import com.sun.jmx.snmp.agent.SnmpMibSubRequest; 59 import com.sun.jmx.snmp.agent.SnmpStandardObjectServer; 60 61 import sun.management.snmp.jvmmib.JvmRTClassPathTableMeta; 62 import sun.management.snmp.util.SnmpCachedData; 63 import sun.management.snmp.util.SnmpTableCache; 64 import sun.management.snmp.util.SnmpTableHandler; 65 import sun.management.snmp.util.MibLogger; 66 import sun.management.snmp.util.JvmContextFactory; 67 68 /** 69 * The class is used for implementing the "JvmRTClassPathTable". 70 */ 71 public class JvmRTClassPathTableMetaImpl extends JvmRTClassPathTableMeta { 72 73 static final long serialVersionUID = -6914494148818455166L; 74 75 private SnmpTableCache cache; 76 77 /** 78 * A concrete implementation of {@link SnmpTableCache}, for the 79 * JvmRTClassPathTable. 80 **/ 81 private static class JvmRTClassPathTableCache extends SnmpTableCache { 82 static final long serialVersionUID = 3805032372592117315L; 83 private JvmRTClassPathTableMetaImpl meta; 84 85 JvmRTClassPathTableCache(JvmRTClassPathTableMetaImpl meta, 86 long validity) { 87 this.meta = meta; 88 this.validity = validity; 89 } 90 91 /** 92 * Call <code>getTableDatas(JvmContextFactory.getUserData())</code>. 93 **/ 94 public SnmpTableHandler getTableHandler() { 95 final Map<Object, Object> userData = JvmContextFactory.getUserData(); 96 return getTableDatas(userData); 97 } 98 99 100 /** 101 * Return a table handler containing the Thread indexes. 102 * Indexes are computed from the ThreadId. 103 **/ 104 protected SnmpCachedData updateCachedDatas(Object userData) { 105 106 107 // We are getting all the input args 108 final String[] path = 109 JvmRuntimeImpl.getClassPath(userData); 110 111 // Time stamp for the cache 112 final long time = System.currentTimeMillis(); 113 final int len = path.length; 114 115 SnmpOid indexes[] = new SnmpOid[len]; 116 117 for(int i = 0; i < len; i++) { 118 indexes[i] = new SnmpOid(i + 1); 119 } 120 121 return new SnmpCachedData(time, indexes, path); 122 } 123 } 124 125 /** 126 * Constructor for the table. Initialize metadata for 127 * "JvmRTClassPathTableMeta". 128 * The reference on the MBean server is updated so the entries 129 * created through an SNMP SET will be AUTOMATICALLY REGISTERED 130 * in Java DMK. 131 */ 132 public JvmRTClassPathTableMetaImpl(SnmpMib myMib, 133 SnmpStandardObjectServer objserv) { 134 super(myMib, objserv); 135 cache = new JvmRTClassPathTableCache(this, -1); 136 } 137 138 // See com.sun.jmx.snmp.agent.SnmpMibTable 139 protected SnmpOid getNextOid(Object userData) 140 throws SnmpStatusException { 141 // null means get the first OID. 142 return getNextOid(null,userData); 143 } 144 145 // See com.sun.jmx.snmp.agent.SnmpMibTable 146 protected SnmpOid getNextOid(SnmpOid oid, Object userData) 147 throws SnmpStatusException { 148 final boolean dbg = log.isDebugOn(); 149 if (dbg) log.debug("getNextOid", "previous=" + oid); 150 151 152 // Get the data handler. 153 // 154 SnmpTableHandler handler = getHandler(userData); 155 if (handler == null) { 156 // This should never happen. 157 // If we get here it's a bug. 158 // 159 if (dbg) log.debug("getNextOid", "handler is null!"); 160 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 161 } 162 163 // Get the next oid 164 // 165 final SnmpOid next = handler.getNext(oid); 166 if (dbg) log.debug("*** **** **** **** getNextOid", "next=" + next); 167 168 // if next is null: we reached the end of the table. 169 // 170 if (next == null) 171 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 172 173 return next; 174 } 175 176 177 // See com.sun.jmx.snmp.agent.SnmpMibTable 178 protected boolean contains(SnmpOid oid, Object userData) { 179 180 // Get the handler. 181 // 182 SnmpTableHandler handler = getHandler(userData); 183 184 // handler should never be null. 185 // 186 if (handler == null) 187 return false; 188 189 return handler.contains(oid); 190 } 191 192 // See com.sun.jmx.snmp.agent.SnmpMibTable 193 public Object getEntry(SnmpOid oid) 194 throws SnmpStatusException { 195 final boolean dbg = log.isDebugOn(); 196 if (dbg) log.debug("getEntry", "oid [" + oid + "]"); 197 if (oid == null || oid.getLength() != 1) { 198 if (dbg) log.debug("getEntry", "Invalid oid [" + oid + "]"); 199 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 200 } 201 202 // Get the request contextual cache (userData). 203 // 204 final Map<Object, Object> m = JvmContextFactory.getUserData(); 205 206 // We're going to use this name to store/retrieve the entry in 207 // the request contextual cache. 208 // 209 // Revisit: Probably better programming to put all these strings 210 // in some interface. 211 // 212 final String entryTag = ((m==null)?null: 213 ("JvmRTClassPathTable.entry." + 214 oid.toString())); 215 216 // If the entry is in the cache, simply return it. 217 // 218 if (m != null) { 219 final Object entry = m.get(entryTag); 220 if (entry != null) { 221 if (dbg) 222 log.debug("getEntry", "Entry is already in the cache"); 223 return entry; 224 } else 225 if (dbg) log.debug("getEntry", "Entry is not in the cache"); 226 } 227 228 // The entry was not in the cache, make a new one. 229 // 230 // Get the data hanler. 231 // 232 SnmpTableHandler handler = getHandler(m); 233 234 // handler should never be null. 235 // 236 if (handler == null) 237 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 238 239 // Get the data associated with our entry. 240 // 241 final Object data = handler.getData(oid); 242 243 // data may be null if the OID we were given is not valid. 244 // 245 if (data == null) 246 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 247 248 // make the new entry (transient object that will be kept only 249 // for the duration of the request. 250 // 251 if (dbg) 252 log.debug("getEntry","data is a: " + data.getClass().getName()); 253 final Object entry = 254 new JvmRTClassPathEntryImpl((String) data, (int) oid.getOidArc(0)); 255 256 // Put the entry in the cache in case we need it later while processing 257 // the request. 258 // 259 if (m != null && entry != null) { 260 m.put(entryTag,entry); 261 } 262 263 return entry; 264 } 265 266 /** 267 * Get the SnmpTableHandler that holds the jvmThreadInstanceTable data. 268 * First look it up in the request contextual cache, and if it is 269 * not found, obtain it from the weak cache. 270 * <br>The request contextual cache will be released at the end of the 271 * current requests, and is used only to process this request. 272 * <br>The weak cache is shared by all requests, and is only 273 * recomputed when it is found to be obsolete. 274 * <br>Note that the data put in the request contextual cache is 275 * never considered to be obsolete, in order to preserve data 276 * coherency. 277 **/ 278 protected SnmpTableHandler getHandler(Object userData) { 279 final Map<Object, Object> m; 280 if (userData instanceof Map) m=Util.cast(userData); 281 else m=null; 282 283 // Look in the contextual cache. 284 if (m != null) { 285 final SnmpTableHandler handler = 286 (SnmpTableHandler)m.get("JvmRTClassPathTable.handler"); 287 if (handler != null) return handler; 288 } 289 290 // No handler in contextual cache, make a new one. 291 final SnmpTableHandler handler = cache.getTableHandler(); 292 293 if (m != null && handler != null ) 294 m.put("JvmRTClassPathTable.handler",handler); 295 296 return handler; 297 } 298 299 static final MibLogger log = 300 new MibLogger(JvmRTClassPathTableMetaImpl.class); 301 }