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.JvmRTLibraryPathTableMeta; 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 "JvmRTLibraryPathTable". 70 */ 71 public class JvmRTLibraryPathTableMetaImpl extends JvmRTLibraryPathTableMeta { 72 73 static final long serialVersionUID = 6713252710712502068L; 74 private SnmpTableCache cache; 75 76 /** 77 * A concrete implementation of {@link SnmpTableCache}, for the 78 * JvmRTLibraryPathTable. 79 **/ 80 private static class JvmRTLibraryPathTableCache extends SnmpTableCache { 81 static final long serialVersionUID = 2035304445719393195L; 82 private JvmRTLibraryPathTableMetaImpl meta; 83 84 JvmRTLibraryPathTableCache(JvmRTLibraryPathTableMetaImpl meta, 85 long validity) { 86 this.meta = meta; 87 this.validity = validity; 88 } 89 90 /** 91 * Call <code>getTableDatas(JvmContextFactory.getUserData())</code>. 92 **/ 93 public SnmpTableHandler getTableHandler() { 94 final Map<Object,Object> userData = JvmContextFactory.getUserData(); 95 return getTableDatas(userData); 96 } 97 98 99 /** 100 * Return a table handler containing the Thread indexes. 101 * Indexes are computed from the ThreadId. 102 **/ 103 protected SnmpCachedData updateCachedDatas(Object userData) { 104 105 106 // We are getting all the input args 107 final String[] path = 108 JvmRuntimeImpl.getLibraryPath(userData); 109 110 // Time stamp for the cache 111 final long time = System.currentTimeMillis(); 112 final int len = path.length; 113 114 SnmpOid indexes[] = new SnmpOid[len]; 115 116 for(int i = 0; i < len; i++) { 117 indexes[i] = new SnmpOid(i + 1); 118 } 119 120 return new SnmpCachedData(time, indexes, path); 121 } 122 } 123 124 /** 125 * Constructor for the table. Initialize metadata for 126 * "JvmRTLibraryPathTableMeta". 127 * The reference on the MBean server is updated so the entries 128 * created through an SNMP SET will be AUTOMATICALLY REGISTERED 129 * in Java DMK. 130 */ 131 public JvmRTLibraryPathTableMetaImpl(SnmpMib myMib, 132 SnmpStandardObjectServer objserv) { 133 super(myMib, objserv); 134 cache = new JvmRTLibraryPathTableCache(this, -1); 135 } 136 137 // See com.sun.jmx.snmp.agent.SnmpMibTable 138 protected SnmpOid getNextOid(Object userData) 139 throws SnmpStatusException { 140 // null means get the first OID. 141 return getNextOid(null,userData); 142 } 143 144 // See com.sun.jmx.snmp.agent.SnmpMibTable 145 protected SnmpOid getNextOid(SnmpOid oid, Object userData) 146 throws SnmpStatusException { 147 final boolean dbg = log.isDebugOn(); 148 if (dbg) log.debug("getNextOid", "previous=" + oid); 149 150 151 // Get the data handler. 152 // 153 SnmpTableHandler handler = getHandler(userData); 154 if (handler == null) { 155 // This should never happen. 156 // If we get here it's a bug. 157 // 158 if (dbg) log.debug("getNextOid", "handler is null!"); 159 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 160 } 161 162 // Get the next oid 163 // 164 final SnmpOid next = handler.getNext(oid); 165 if (dbg) log.debug("*** **** **** **** getNextOid", "next=" + next); 166 167 // if next is null: we reached the end of the table. 168 // 169 if (next == null) 170 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 171 172 return next; 173 } 174 175 176 // See com.sun.jmx.snmp.agent.SnmpMibTable 177 protected boolean contains(SnmpOid oid, Object userData) { 178 179 // Get the handler. 180 // 181 SnmpTableHandler handler = getHandler(userData); 182 183 // handler should never be null. 184 // 185 if (handler == null) 186 return false; 187 188 return handler.contains(oid); 189 } 190 191 // See com.sun.jmx.snmp.agent.SnmpMibTable 192 public Object getEntry(SnmpOid oid) 193 throws SnmpStatusException { 194 final boolean dbg = log.isDebugOn(); 195 if (dbg) log.debug("getEntry", "oid [" + oid + "]"); 196 if (oid == null || oid.getLength() != 1) { 197 if (dbg) log.debug("getEntry", "Invalid oid [" + oid + "]"); 198 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 199 } 200 201 // Get the request contextual cache (userData). 202 // 203 final Map<Object, Object> m = JvmContextFactory.getUserData(); 204 205 // We're going to use this name to store/retrieve the entry in 206 // the request contextual cache. 207 // 208 // Revisit: Probably better programming to put all these strings 209 // in some interface. 210 // 211 final String entryTag = ((m==null)?null: 212 ("JvmRTLibraryPathTable.entry." + 213 oid.toString())); 214 215 // If the entry is in the cache, simply return it. 216 // 217 if (m != null) { 218 final Object entry = m.get(entryTag); 219 if (entry != null) { 220 if (dbg) 221 log.debug("getEntry", "Entry is already in the cache"); 222 return entry; 223 } else if (dbg) log.debug("getEntry", "Entry is not in the cache"); 224 225 } 226 227 // The entry was not in the cache, make a new one. 228 // 229 // Get the data hanler. 230 // 231 SnmpTableHandler handler = getHandler(m); 232 233 // handler should never be null. 234 // 235 if (handler == null) 236 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 237 238 // Get the data associated with our entry. 239 // 240 final Object data = handler.getData(oid); 241 242 // data may be null if the OID we were given is not valid. 243 // 244 if (data == null) 245 throw new SnmpStatusException(SnmpStatusException.noSuchInstance); 246 247 // make the new entry (transient object that will be kept only 248 // for the duration of the request. 249 // 250 if (dbg) log.debug("getEntry","data is a: "+ 251 data.getClass().getName()); 252 final Object entry = 253 new JvmRTLibraryPathEntryImpl((String) data,(int)oid.getOidArc(0)); 254 255 // Put the entry in the cache in case we need it later while processing 256 // the request. 257 // 258 if (m != null && entry != null) { 259 m.put(entryTag,entry); 260 } 261 262 return entry; 263 } 264 265 /** 266 * Get the SnmpTableHandler that holds the jvmThreadInstanceTable data. 267 * First look it up in the request contextual cache, and if it is 268 * not found, obtain it from the weak cache. 269 * <br>The request contextual cache will be released at the end of the 270 * current requests, and is used only to process this request. 271 * <br>The weak cache is shared by all requests, and is only 272 * recomputed when it is found to be obsolete. 273 * <br>Note that the data put in the request contextual cache is 274 * never considered to be obsolete, in order to preserve data 275 * coherency. 276 **/ 277 protected SnmpTableHandler getHandler(Object userData) { 278 final Map<Object, Object> m; 279 if (userData instanceof Map) m=Util.cast(userData); 280 else m=null; 281 282 // Look in the contextual cache. 283 if (m != null) { 284 final SnmpTableHandler handler = 285 (SnmpTableHandler)m.get("JvmRTLibraryPathTable.handler"); 286 if (handler != null) return handler; 287 } 288 289 // No handler in contextual cache, make a new one. 290 final SnmpTableHandler handler = cache.getTableHandler(); 291 292 if (m != null && handler != null ) 293 m.put("JvmRTLibraryPathTable.handler",handler); 294 295 return handler; 296 } 297 298 static final MibLogger log = 299 new MibLogger(JvmRTLibraryPathTableMetaImpl.class); 300 }