blob: 806d8610802e7dd4472f931d21a7cc73ba679424 [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
28// java imports
29//
30import com.sun.jmx.mbeanserver.Util;
31import java.io.Serializable;
32import java.util.List;
33import java.util.Map;
34import java.util.TreeMap;
35
36// jmx imports
37//
38import com.sun.jmx.snmp.SnmpOid;
39import com.sun.jmx.snmp.SnmpStatusException;
40
41// jdmk imports
42//
43import com.sun.jmx.snmp.agent.SnmpMib;
44import com.sun.jmx.snmp.agent.SnmpStandardObjectServer;
45
46import java.lang.management.MemoryManagerMXBean;
47import java.lang.management.ManagementFactory;
48
49import sun.management.snmp.jvmmib.JvmMemManagerTableMeta;
50import sun.management.snmp.util.SnmpTableCache;
51import sun.management.snmp.util.SnmpNamedListTableCache;
52import sun.management.snmp.util.SnmpTableHandler;
53import sun.management.snmp.util.MibLogger;
54import sun.management.snmp.util.JvmContextFactory;
55
56/**
57 * The class is used for implementing the "JvmMemManagerTable" table.
58 *
59 * This custom implementation show how to implement an SNMP table
60 * over a weak cache, recomputing the cahed data when needed.
61 */
62public class JvmMemManagerTableMetaImpl extends JvmMemManagerTableMeta {
63
64 /**
65 * A concrete implementation of {@link SnmpNamedListTableCache}, for the
66 * jvmMemManagerTable.
67 **/
68 private static class JvmMemManagerTableCache
69 extends SnmpNamedListTableCache {
70 /**
71 * Create a weak cache for the jvmMemManagerTable.
72 * @param validity validity of the cached data, in ms.
73 **/
74 JvmMemManagerTableCache(long validity) {
75 this.validity = validity;
76 }
77
78 /**
79 * Use the MemoryManagerMXBean name as key.
80 * @param context A {@link TreeMap} as allocated by the parent
81 * {@link SnmpNamedListTableCache} class.
82 * @param rawDatas List of {@link MemoryManagerMXBean}, as
83 * returned by
84 * <code>ManagementFactory.getMemoryMBean().getMemoryManagers()</code>
85 * @param rank The <var>rank</var> of <var>item</var> in the list.
86 * @param item The <var>rank</var><super>th</super>
87 * <code>MemoryManagerMXBean</code> in the list.
88 * @return <code>((MemoryManagerMXBean)item).getName()</code>
89 **/
90 protected String getKey(Object context, List rawDatas,
91 int rank, Object item) {
92 if (item == null) return null;
93 final String name = ((MemoryManagerMXBean)item).getName();
94 log.debug("getKey", "key=" + name);
95 return name;
96 }
97
98 /**
99 * Call <code>getTableHandler(JvmContextFactory.getUserData())</code>.
100 **/
101 public SnmpTableHandler getTableHandler() {
102 final Map userData = JvmContextFactory.getUserData();
103 return getTableDatas(userData);
104 }
105
106 /**
107 * Return the key used to cache the raw data of this table.
108 **/
109 protected String getRawDatasKey() {
110 return "JvmMemManagerTable.getMemoryManagers";
111 }
112
113 /**
114 * Call ManagementFactory.getMemoryManagerMXBeans() to
115 * load the raw data of this table.
116 **/
117 protected List loadRawDatas(Map userData) {
118 return ManagementFactory.getMemoryManagerMXBeans();
119 }
120
121 }
122
123 // The weak cache for this table.
124 protected SnmpTableCache cache;
125
126 /**
127 * Constructor for the table. Initialize metadata for
128 * "JvmMemManagerTableMeta".
129 * The reference on the MBean server is updated so the entries
130 * created through an SNMP SET will be AUTOMATICALLY REGISTERED
131 * in Java DMK.
132 */
133 public JvmMemManagerTableMetaImpl(SnmpMib myMib,
134 SnmpStandardObjectServer objserv) {
135 super(myMib,objserv);
136 this.cache = new
137 JvmMemManagerTableCache(((JVM_MANAGEMENT_MIB_IMPL)myMib).
138 validity());
139 }
140
141 // See com.sun.jmx.snmp.agent.SnmpMibTable
142 protected SnmpOid getNextOid(Object userData)
143 throws SnmpStatusException {
144 // null means get the first OID.
145 return getNextOid(null,userData);
146 }
147
148 // See com.sun.jmx.snmp.agent.SnmpMibTable
149 protected SnmpOid getNextOid(SnmpOid oid, Object userData)
150 throws SnmpStatusException {
151 final boolean dbg = log.isDebugOn();
152 if (dbg) log.debug("getNextOid", "previous=" + oid);
153
154
155 // Get the data handler.
156 //
157 SnmpTableHandler handler = getHandler(userData);
158 if (handler == null) {
159 // This should never happen.
160 // If we get here it's a bug.
161 //
162 if (dbg) log.debug("getNextOid", "handler is null!");
163 throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
164 }
165
166 // Get the next oid
167 //
168 final SnmpOid next = handler.getNext(oid);
169 if (dbg) log.debug("getNextOid", "next=" + next);
170
171 // if next is null: we reached the end of the table.
172 //
173 if (next == null)
174 throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
175
176 return next;
177 }
178
179
180 // See com.sun.jmx.snmp.agent.SnmpMibTable
181 protected boolean contains(SnmpOid oid, Object userData) {
182
183 // Get the handler.
184 //
185 SnmpTableHandler handler = getHandler(userData);
186
187 // handler should never be null.
188 //
189 if (handler == null)
190 return false;
191
192 return handler.contains(oid);
193 }
194
195 // See com.sun.jmx.snmp.agent.SnmpMibTable
196 public Object getEntry(SnmpOid oid)
197 throws SnmpStatusException {
198
199 if (oid == null)
200 throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
201
202 // Get the request contextual cache (userData).
203 //
204 final Map<Object, Object> m = JvmContextFactory.getUserData();
205
206 // We know in the case of this table that the index is an integer,
207 // it is thus the first OID arc of the index OID.
208 //
209 final long index = oid.getOidArc(0);
210
211 // We're going to use this name to store/retrieve the entry in
212 // the request contextual cache.
213 //
214 // Revisit: Probably better programming to put all these strings
215 // in some interface.
216 //
217 final String entryTag = ((m==null)?null:("JvmMemManagerTable.entry." +
218 index));
219
220 // If the entry is in the cache, simply return it.
221 //
222 if (m != null) {
223 final Object entry = m.get(entryTag);
224 if (entry != null) return entry;
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 final Object entry =
251 new JvmMemManagerEntryImpl((MemoryManagerMXBean)data,(int)index);
252
253 // Put the entry in the cache in case we need it later while processing
254 // the request.
255 //
256 if (m != null && entry != null) {
257 m.put(entryTag,entry);
258 }
259
260 return entry;
261 }
262
263 /**
264 * Get the SnmpTableHandler that holds the jvmMemManagerTable data.
265 * First look it up in the request contextual cache, and if it is
266 * not found, obtain it from the weak cache.
267 * <br>The request contextual cache will be released at the end of the
268 * current requests, and is used only to process this request.
269 * <br>The weak cache is shared by all requests, and is only
270 * recomputed when it is found to be obsolete.
271 * <br>Note that the data put in the request contextual cache is
272 * never considered to be obsolete, in order to preserve data
273 * coherency.
274 **/
275 protected SnmpTableHandler getHandler(Object userData) {
276 final Map<Object, Object> m;
277 if (userData instanceof Map) m=Util.cast(userData);
278 else m=null;
279
280 // Look in the contextual cache.
281 if (m != null) {
282 final SnmpTableHandler handler =
283 (SnmpTableHandler)m.get("JvmMemManagerTable.handler");
284 if (handler != null) return handler;
285 }
286
287 // No handler in contextual cache, make a new one.
288 final SnmpTableHandler handler = cache.getTableHandler();
289
290 if (m != null && handler != null )
291 m.put("JvmMemManagerTable.handler",handler);
292
293 return handler;
294 }
295
296 static final MibLogger log =
297 new MibLogger(JvmMemManagerTableMetaImpl.class);
298}