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