blob: e61537ee8f0067691ae9309c6772af801aa7bd29 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-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 */
25
26package com.sun.jmx.snmp.agent;
27
28
29
30// java imports
31//
32import java.io.Serializable;
33import java.util.Date;
34import java.util.Vector;
35import java.util.Enumeration;
36import java.util.List;
37import java.util.ArrayList;
38
39// jmx imports
40//
41import javax.management.Notification;
42import javax.management.ObjectName;
43import javax.management.NotificationFilter;
44import javax.management.NotificationListener;
45import javax.management.NotificationBroadcaster;
46import javax.management.MBeanNotificationInfo;
47import javax.management.ListenerNotFoundException;
48import com.sun.jmx.snmp.SnmpOid;
49import com.sun.jmx.snmp.SnmpValue;
50import com.sun.jmx.snmp.SnmpVarBind;
51import com.sun.jmx.snmp.SnmpStatusException;
52
53/**
54 * This class is an abstraction for an SNMP table.
55 * It is the base class for implementing SNMP tables in the
56 * MBean world.
57 *
58 * <p>
59 * Its responsibility is to synchronize the MBean view of the table
60 * (Table of entries) with the MIB view (array of OID indexes). Each
61 * object of this class will be bound to the Metadata object which
62 * manages the same SNMP Table within the MIB.
63 * </p>
64 *
65 * <p>
66 * For each table defined in a MIB, mibgen will generate a specific
67 * class called Table<i>TableName</i> that will subclass this class, and
68 * a corresponding <i>TableName</i>Meta class extending SnmpMibTable
69 * and corresponding to the MIB view of the same table.
70 * </p>
71 *
72 * <p>
73 * Objects of this class are instantiated by MBeans representing
74 * the SNMP Group to which the table belong.
75 * </p>
76 *
77 * <p><b>This API is a Sun Microsystems internal API and is subject
78 * to change without notice.</b></p>
79 * @see com.sun.jmx.snmp.agent.SnmpTableEntryFactory
80 * @see com.sun.jmx.snmp.agent.SnmpMibTable
81 *
82 */
83public abstract class SnmpTableSupport implements SnmpTableEntryFactory,
84// NPCTE fix for bugId 4499265, esc 0, MR 04 sept 2001
85// SnmpTableCallbackHandler {
86 SnmpTableCallbackHandler, Serializable {
87// end of NPCTE fix for bugId 4499265
88
89 //-----------------------------------------------------------------
90 //
91 // Protected Variables
92 //
93 //-----------------------------------------------------------------
94
95 /**
96 * The list of entries
97 **/
98 protected List<Object> entries;
99
100 /**
101 * The associated metadata object
102 **/
103 protected SnmpMibTable meta;
104
105 /**
106 * The MIB to which this table belongs
107 **/
108 protected SnmpMib theMib;
109
110 //-----------------------------------------------------------------
111 //
112 // Private Variables
113 //
114 //-----------------------------------------------------------------
115
116 /**
117 * This variable is initialized while binding this object to its
118 * corresponding meta object.
119 **/
120 private boolean registrationRequired = false;
121
122
123
124 //-----------------------------------------------------------------
125 //
126 // Constructor
127 //
128 //-----------------------------------------------------------------
129
130 /**
131 * Initializes the table.
132 * The steps are these:
133 * <ul><li> allocate an array for storing entry object,</li>
134 * <li> retrieve the corresponding metadata object
135 * from the MIB,
136 * <li> bind this object to the corresponding metadata object
137 * from the MIB.</li>
138 * </ul>
139 *
140 * @param mib The MIB to which this table belong.
141 *
142 **/
143 protected SnmpTableSupport(SnmpMib mib) {
144 theMib = mib;
145 meta = getRegisteredTableMeta(mib);
146 bindWithTableMeta();
147 entries = allocateTable();
148 }
149
150
151 //-----------------------------------------------------------------
152 //
153 // Implementation of the SnmpTableEntryFactory interface
154 //
155 //-----------------------------------------------------------------
156
157 /**
158 * Creates a new entry in the table.
159 *
160 * This factory method is generated by mibgen and used internally.
161 * It is part of the
162 * {@link com.sun.jmx.snmp.agent.SnmpTableEntryFactory} interface.
163 * You may subclass this method to implement any specific behaviour
164 * your application requires.
165 *
166 * @exception SnmpStatusException if the entry cannot be created.
167 **/
168 public abstract void createNewEntry(SnmpMibSubRequest request,
169 SnmpOid rowOid, int depth,
170 SnmpMibTable meta)
171 throws SnmpStatusException;
172
173
174 //-----------------------------------------------------------------
175 //
176 // Public methods
177 //
178 //-----------------------------------------------------------------
179
180 /**
181 * Returns the entry located at the given position in the table.
182 *
183 * @return The entry located at the given position, <code>null</code>
184 * if no entry can be found at this position.
185 **/
186 // XXXX xxxx zzz ZZZZ => public? or protected?
187 public Object getEntry(int pos) {
188 if (entries == null) return null;
189 return entries.get(pos);
190 }
191
192 /**
193 * Returns the number of entries registered in the table.
194 *
195 * @return The number of entries registered in the table.
196 **/
197 public int getSize() {
198 return meta.getSize();
199 }
200
201 /**
202 * This method lets you dynamically switch the creation policy.
203 *
204 * <CODE>setCreationEnabled()</CODE> will switch the policy of
205 * remote entry creation via SET operations, by calling
206 * <code>setCreationEnabled()</code> on the metadata object
207 * associated with this table.
208 * <BR> By default remote entry creation via SET operation is disabled.
209 *
210 * @param remoteCreationFlag Tells whether remote entry creation must
211 * be enabled or disabled.
212 * <li>
213 * <CODE>setCreationEnabled(true)</CODE> will enable remote entry
214 * creation via SET operations.</li>
215 * <li>
216 * <CODE>setCreationEnabled(false)</CODE> will disable remote entry
217 * creation via SET operations.</li>
218 * <p> By default remote entry creation via SET operation is disabled.
219 * </p>
220 *
221 * @see com.sun.jmx.snmp.agent.SnmpMibTable
222 *
223 **/
224 public void setCreationEnabled(boolean remoteCreationFlag) {
225 meta.setCreationEnabled(remoteCreationFlag);
226 }
227
228 /**
229 * Tells whether a new entry should be created when a SET operation
230 * is received for an entry that does not exist yet.
231 * This method calls <code>isCreationEnabled()</code> on the metadata
232 * object associated with this table.
233 *
234 * @return true if a new entry must be created, false otherwise.<br>
235 * [default: returns <CODE>false</CODE>]
236 *
237 * @see com.sun.jmx.snmp.agent.SnmpMibTable
238 **/
239 public boolean isCreationEnabled() {
240 return meta.isCreationEnabled();
241 }
242
243 /**
244 * Tells whether the metadata object to which this table is linked
245 * requires entries to be registered. In this case passing an
246 * ObjectName when registering entries will be mandatory.
247 *
248 * @return <code>true</code> if the associated metadata requires entries
249 * to be registered (mibgen generated generic metadata).
250 **/
251 public boolean isRegistrationRequired() {
252 return registrationRequired;
253 }
254
255 /**
256 * Builds an entry SnmpIndex from its row OID.
257 *
258 * This method is generated by mibgen and used internally.
259 *
260 * @param rowOid The SnmpOid object identifying a table entry.
261 *
262 * @return The SnmpIndex of the entry identified by <code>rowOid</code>.
263 *
264 * @exception SnmpStatusException if the index cannot be built from the
265 * given OID.
266 **/
267 public SnmpIndex buildSnmpIndex(SnmpOid rowOid)
268 throws SnmpStatusException {
269 return buildSnmpIndex(rowOid.longValue(false), 0);
270 }
271
272 /**
273 * Builds an SnmpOid from an SnmpIndex object.
274 *
275 * This method is generated by mibgen and used internally.
276 *
277 * @param index An SnmpIndex object identifying a table entry.
278 *
279 * @return The SnmpOid form of the given entry index.
280 *
281 * @exception SnmpStatusException if the given index is not valid.
282 **/
283 public abstract SnmpOid buildOidFromIndex(SnmpIndex index)
284 throws SnmpStatusException;
285
286 /**
287 * Builds the default ObjectName of an entry from the SnmpIndex
288 * identifying this entry. No access is made on the entry itself.
289 *
290 * This method is generated by mibgen and used internally.
291 * You can subclass this method if you want to change the default
292 * ObjectName policy. This is only meaningfull when entries
293 * are registered MBeans.
294 *
295 * @param index The SnmpIndex identifying the entry from which we
296 * want to build the default ObjectName.
297 *
298 * @return The default ObjectName for the entry identified by
299 * the given index.
300 *
301 * @exception SnmpStatusException if the given index is not valid.
302 **/
303 public abstract ObjectName buildNameFromIndex(SnmpIndex index)
304 throws SnmpStatusException;
305
306
307 //-----------------------------------------------------------------
308 //
309 // Implementation of the SnmpTableEntryFactory interface
310 //
311 //-----------------------------------------------------------------
312
313 /**
314 * This callback is called by the associated metadata object
315 * when a new table entry has been registered in the
316 * table metadata.
317 *
318 * This method will update the <code>entries</code> list.
319 *
320 * @param pos The position at which the new entry was inserted
321 * in the table.
322 * @param row The row OID of the new entry
323 * @param name The ObjectName of the new entry (as specified by the
324 * factory)
325 * @param entry The new entry (as returned by the factory)
326 * @param meta The table metadata object.
327 *
328 **/
329 public void addEntryCb(int pos, SnmpOid row, ObjectName name,
330 Object entry, SnmpMibTable meta)
331 throws SnmpStatusException {
332 try {
333 if (entries != null) entries.add(pos,entry);
334 } catch (Exception e) {
335 throw new SnmpStatusException(SnmpStatusException.noSuchName);
336 }
337 }
338
339 /**
340 * This callback is called by the associated metadata object
341 * when a new table entry has been removed from the
342 * table metadata.
343 *
344 * This method will update the <code>entries</code> list.
345 *
346 * @param pos The position from which the entry was deleted
347 * @param row The row OID of the deleted entry
348 * @param name The ObjectName of the deleted entry (may be null if
349 * ObjectName's were not required)
350 * @param entry The deleted entry (may be null if only ObjectName's
351 * were required)
352 * @param meta The table metadata object.
353 *
354 **/
355 public void removeEntryCb(int pos, SnmpOid row, ObjectName name,
356 Object entry, SnmpMibTable meta)
357 throws SnmpStatusException {
358 try {
359 if (entries != null) entries.remove(pos);
360 } catch (Exception e) {
361 }
362 }
363
364
365
366 /**
367 * Enables to add an SNMP entry listener to this
368 * <CODE>SnmpMibTable</CODE>.
369 *
370 * @param listener The listener object which will handle the
371 * notifications emitted by the registered MBean.
372 *
373 * @param filter The filter object. If filter is null, no filtering
374 * will be performed before handling notifications.
375 *
376 * @param handback The context to be sent to the listener when a
377 * notification is emitted.
378 *
379 * @exception IllegalArgumentException Listener parameter is null.
380 */
381 public void
382 addNotificationListener(NotificationListener listener,
383 NotificationFilter filter, Object handback) {
384 meta.addNotificationListener(listener,filter,handback);
385 }
386
387 /**
388 * Enables to remove an SNMP entry listener from this
389 * <CODE>SnmpMibTable</CODE>.
390 *
391 * @param listener The listener object which will handle the
392 * notifications emitted by the registered MBean.
393 * This method will remove all the information related to this
394 * listener.
395 *
396 * @exception ListenerNotFoundException The listener is not registered
397 * in the MBean.
398 */
399 public synchronized void
400 removeNotificationListener(NotificationListener listener)
401 throws ListenerNotFoundException {
402 meta.removeNotificationListener(listener);
403 }
404
405 /**
406 * Returns a <CODE>NotificationInfo</CODE> object containing the
407 * notification class and the notification type sent by the
408 * <CODE>SnmpMibTable</CODE>.
409 */
410 public MBeanNotificationInfo[] getNotificationInfo() {
411 return meta.getNotificationInfo();
412 }
413
414 //-----------------------------------------------------------------
415 //
416 // Protected Abstract methods
417 //
418 //-----------------------------------------------------------------
419
420 /**
421 * Builds an SnmpIndex object from the index part of an OID.
422 *
423 * This method is generated by mibgen and used internally.
424 *
425 * @param oid The OID from which to build the index, represented
426 * as an array of long.
427 * @param start The position where to start from in the OID array.
428 *
429 * @return The SnmpOid form of the given entry index.
430 *
431 * @exception SnmpStatusException if the given index is not valid.
432 **/
433 protected abstract SnmpIndex buildSnmpIndex(long oid[], int start )
434 throws SnmpStatusException;
435
436 /**
437 * Returns the metadata object associated with this table.
438 *
439 * This method is generated by mibgen and used internally.
440 *
441 * @param mib The SnmpMib object holding the Metadata corresponding
442 * to this table.
443 *
444 * @return The metadata object associated with this table.
445 * Returns <code>null</code> if this implementation of the
446 * MIB doesn't support this table.
447 **/
448 protected abstract SnmpMibTable getRegisteredTableMeta(SnmpMib mib);
449
450
451 //-----------------------------------------------------------------
452 //
453 // Protected methods
454 //
455 //-----------------------------------------------------------------
456
457 /**
458 * Allocates an ArrayList for storing table entries.
459 *
460 * This method is called within the constructor at object creation.
461 * Any object implementing the {@link java.util.List} interface can
462 * be used.
463 *
464 * @return A new list in which to store entries. If <code>null</code>
465 * is returned then no entry will be stored in the list
466 * and getEntry() will always return null.
467 **/
468 protected List<Object> allocateTable() {
469 return new ArrayList<Object>();
470 }
471
472 /**
473 * Add an entry in this table.
474 *
475 * This method registers an entry in the table and perform
476 * synchronization with the associated table metadata object.
477 *
478 * This method assumes that the given entry will not be registered,
479 * or will be registered with its default ObjectName built from the
480 * associated SnmpIndex.
481 * <p>
482 * If the entry is going to be registered, then
483 * {@link com.sun.jmx.snmp.agent.SnmpTableSupport#addEntry(SnmpIndex, ObjectName, Object)} should be prefered.
484 * <br> This function is mainly provided for backward compatibility.
485 *
486 * @param index The SnmpIndex built from the given entry.
487 * @param entry The entry that should be added in the table.
488 *
489 * @exception SnmpStatusException if the entry cannot be registered with
490 * the given index.
491 **/
492 protected void addEntry(SnmpIndex index, Object entry)
493 throws SnmpStatusException {
494 SnmpOid oid = buildOidFromIndex(index);
495 ObjectName name = null;
496 if (isRegistrationRequired()) {
497 name = buildNameFromIndex(index);
498 }
499 meta.addEntry(oid,name,entry);
500 }
501
502 /**
503 * Add an entry in this table.
504 *
505 * This method registers an entry in the table and performs
506 * synchronization with the associated table metadata object.
507 *
508 * @param index The SnmpIndex built from the given entry.
509 * @param name The ObjectName with which this entry will be registered.
510 * @param entry The entry that should be added in the table.
511 *
512 * @exception SnmpStatusException if the entry cannot be registered with
513 * the given index.
514 **/
515 protected void addEntry(SnmpIndex index, ObjectName name, Object entry)
516 throws SnmpStatusException {
517 SnmpOid oid = buildOidFromIndex(index);
518 meta.addEntry(oid,name,entry);
519 }
520
521 /**
522 * Remove an entry from this table.
523 *
524 * This method unregisters an entry from the table and performs
525 * synchronization with the associated table metadata object.
526 *
527 * @param index The SnmpIndex identifying the entry.
528 * @param entry The entry that should be removed in the table. This
529 * parameter is optional and can be omitted if it doesn't
530 * need to be passed along to the
531 * <code>removeEntryCb()</code> callback defined in the
532 * {@link com.sun.jmx.snmp.agent.SnmpTableCallbackHandler}
533 * interface.
534 *
535 * @exception SnmpStatusException if the entry cannot be unregistered.
536 **/
537 protected void removeEntry(SnmpIndex index, Object entry)
538 throws SnmpStatusException {
539 SnmpOid oid = buildOidFromIndex(index);
540 meta.removeEntry(oid,entry);
541 }
542
543 // protected void removeEntry(ObjectName name, Object entry)
544 // throws SnmpStatusException {
545 // meta.removeEntry(name,entry);
546 // }
547
548 /**
549 * Returns the entries in the table.
550 *
551 * @return An Object[] array containing the entries registered in the
552 * table.
553 **/
554 protected Object[] getBasicEntries() {
555 if (entries == null) return null;
556 Object[] array= new Object[entries.size()];
557 entries.toArray(array);
558 return array;
559 }
560
561 /**
562 * Binds this table with its associated metadata, registering itself
563 * as an SnmpTableEntryFactory.
564 **/
565 protected void bindWithTableMeta() {
566 if (meta == null) return;
567 registrationRequired = meta.isRegistrationRequired();
568 meta.registerEntryFactory(this);
569 }
570
571}