blob: 8c16f5f9311dcd2179011877487558526ae44a74 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package sun.management.snmp.jvminstr;
26
27// java imports
28//
29import com.sun.jmx.mbeanserver.Util;
30import java.io.Serializable;
31import java.util.List;
32import java.util.Map;
33import java.util.TreeMap;
34
35
36// jmx imports
37//
38import javax.management.MBeanServer;
39import javax.management.ObjectName;
40import com.sun.jmx.snmp.SnmpOid;
41import com.sun.jmx.snmp.SnmpStatusException;
42
43// jdmk imports
44//
45import com.sun.jmx.snmp.agent.SnmpMib;
46import com.sun.jmx.snmp.agent.SnmpMibSubRequest;
47import com.sun.jmx.snmp.agent.SnmpStandardObjectServer;
48
49import java.lang.management.MemoryPoolMXBean;
50import java.lang.management.ManagementFactory;
51
52import sun.management.snmp.jvmmib.JvmMemPoolTableMeta;
53import sun.management.snmp.util.SnmpTableCache;
54import sun.management.snmp.util.SnmpNamedListTableCache;
55import sun.management.snmp.util.SnmpTableHandler;
56import sun.management.snmp.util.MibLogger;
57import sun.management.snmp.util.JvmContextFactory;
58
59/**
60 * The class is used for implementing the "JvmMemPoolTable" group.
61 */
62public class JvmMemPoolTableMetaImpl extends JvmMemPoolTableMeta {
63
64 /**
65 * A concrete implementation of {@link SnmpNamedListTableCache}, for the
66 * jvmMemPoolTable.
67 **/
68 private static class JvmMemPoolTableCache extends SnmpNamedListTableCache {
69 /**
70 * Create a weak cache for the jvmMemPoolTable.
71 * @param validity validity of the cached data, in ms.
72 **/
73 JvmMemPoolTableCache(long validity) {
74 this.validity = validity;
75 }
76
77 /**
78 * Use the MemoryPoolMXBean name as key.
79 * @param context A {@link TreeMap} as allocated by the parent
80 * {@link SnmpNamedListTableCache} class.
81 * @param rawDatas List of {@link MemoryPoolMXBean}, as
82 * returned by
83 * <code>ManagementFactory.getMemoryPoolMXBeans()</code>
84 * @param rank The <var>rank</var> of <var>item</var> in the list.
85 * @param item The <var>rank</var><super>th</super>
86 * <code>MemoryPoolMXBean</code> in the list.
87 * @return <code>((MemoryPoolMXBean)item).getName()</code>
88 **/
89 protected String getKey(Object context, List rawDatas,
90 int rank, Object item) {
91 if (item == null) return null;
92 final String name = ((MemoryPoolMXBean)item).getName();
93 log.debug("getKey", "key=" + name);
94 return name;
95 }
96
97 /**
98 * Call <code>getTableDatas(JvmContextFactory.getUserData())</code>.
99 **/
100 public SnmpTableHandler getTableHandler() {
101 final Map userData = JvmContextFactory.getUserData();
102 return getTableDatas(userData);
103 }
104
105 /**
106 * Return the key used to cache the raw data of this table.
107 **/
108 protected String getRawDatasKey() {
109 return "JvmMemManagerTable.getMemoryPools";
110 }
111
112 /**
113 * Call ManagementFactory.getMemoryPoolMXBeans() to
114 * load the raw data of this table.
115 **/
116 protected List loadRawDatas(Map userData) {
117 return ManagementFactory.getMemoryPoolMXBeans();
118 }
119 }
120
121 // The weak cache for this table.
122 protected SnmpTableCache cache;
123
124 /**
125 * Constructor for the table.
126 * Initialize metadata for "JvmMemPoolTableMeta".
127 */
128 public JvmMemPoolTableMetaImpl(SnmpMib myMib,
129 SnmpStandardObjectServer objserv) {
130 super(myMib,objserv);
131 this.cache = new
132 JvmMemPoolTableCache(((JVM_MANAGEMENT_MIB_IMPL)myMib).
133 validity()*30);
134 }
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 try {
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
161 SnmpStatusException(SnmpStatusException.noSuchInstance);
162 }
163
164 // Get the next oid
165 //
166 final SnmpOid next = handler.getNext(oid);
167 if (dbg) log.debug("getNextOid", "next=" + next);
168
169 // if next is null: we reached the end of the table.
170 //
171 if (next == null)
172 throw new
173 SnmpStatusException(SnmpStatusException.noSuchInstance);
174
175 return next;
176 } catch (SnmpStatusException x) {
177 if (dbg) log.debug("getNextOid", "End of MIB View: " + x);
178 throw x;
179 } catch (RuntimeException r) {
180 if (dbg) log.debug("getNextOid", "Unexpected exception: " + r);
181 if (dbg) log.debug("getNextOid",r);
182 throw r;
183 }
184 }
185
186
187 // See com.sun.jmx.snmp.agent.SnmpMibTable
188 protected boolean contains(SnmpOid oid, Object userData) {
189
190 // Get the handler.
191 //
192 SnmpTableHandler handler = getHandler(userData);
193
194 // handler should never be null.
195 //
196 if (handler == null)
197 return false;
198
199 return handler.contains(oid);
200 }
201
202 // See com.sun.jmx.snmp.agent.SnmpMibTable
203 public Object getEntry(SnmpOid oid)
204 throws SnmpStatusException {
205
206 if (oid == null)
207 throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
208
209 // Get the request contextual cache (userData).
210 //
211 final Map<Object, Object> m = Util.cast(JvmContextFactory.getUserData());
212
213 // We know in the case of this table that the index is an integer,
214 // it is thus the first OID arc of the index OID.
215 //
216 final long index = oid.getOidArc(0);
217
218 // We're going to use this name to store/retrieve the entry in
219 // the request contextual cache.
220 //
221 // Revisit: Probably better programming to put all these strings
222 // in some interface.
223 //
224 final String entryTag = ((m==null)?null:("JvmMemPoolTable.entry." +
225 index));
226
227 // If the entry is in the cache, simply return it.
228 //
229 if (m != null) {
230 final Object entry = m.get(entryTag);
231 if (entry != null) return entry;
232 }
233
234 // The entry was not in the cache, make a new one.
235 //
236 // Get the data hanler.
237 //
238 SnmpTableHandler handler = getHandler(m);
239
240 // handler should never be null.
241 //
242 if (handler == null)
243 throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
244
245 // Get the data associated with our entry.
246 //
247 final Object data = handler.getData(oid);
248
249 // data may be null if the OID we were given is not valid.
250 //
251 if (data == null)
252 throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
253
254 // make the new entry (transient object that will be kept only
255 // for the duration of the request.
256 //
257 if (log.isDebugOn())
258 log.debug("getEntry","data is a: " + data.getClass().getName());
259 final Object entry =
260 new JvmMemPoolEntryImpl((MemoryPoolMXBean)data,(int)index);
261
262 // Put the entry in the cache in case we need it later while processing
263 // the request.
264 //
265 if (m != null && entry != null) {
266 m.put(entryTag,entry);
267 }
268
269 return entry;
270 }
271
272 /**
273 * Get the SnmpTableHandler that holds the jvmMemPoolTable data.
274 * First look it up in the request contextual cache, and if it is
275 * not found, obtain it from the weak cache.
276 * <br>The request contextual cache will be released at the end of the
277 * current requests, and is used only to process this request.
278 * <br>The weak cache is shared by all requests, and is only
279 * recomputed when it is found to be obsolete.
280 * <br>Note that the data put in the request contextual cache is
281 * never considered to be obsolete, in order to preserve data
282 * coherency.
283 **/
284 protected SnmpTableHandler getHandler(Object userData) {
285 final Map<Object, Object> m;
286 if (userData instanceof Map) m = Util.cast(userData);
287 else m = null;
288
289 // Look in the contextual cache.
290 if (m != null) {
291 final SnmpTableHandler handler =
292 (SnmpTableHandler)m.get("JvmMemPoolTable.handler");
293 if (handler != null) return handler;
294 }
295
296 // No handler in contextual cache, make a new one.
297 final SnmpTableHandler handler = cache.getTableHandler();
298
299 if (m != null && handler != null )
300 m.put("JvmMemPoolTable.handler",handler);
301
302 return handler;
303 }
304
305 static final MibLogger log = new MibLogger(JvmMemPoolTableMetaImpl.class);
306}