KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > agent > agentx > subagent > AgentXSharedMOTableSupport


1 /*_############################################################################
2   _##
3   _## SNMP4J-AgentX - AgentXSharedMOTableSupport.java
4   _##
5   _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
6   _##
7   _## This program is free software; you can redistribute it and/or modify
8   _## it under the terms of the GNU General Public License version 2 as
9   _## published by the Free Software Foundation.
10   _##
11   _## This program is distributed in the hope that it will be useful,
12   _## but WITHOUT ANY WARRANTY; without even the implied warranty of
13   _## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   _## GNU General Public License for more details.
15   _##
16   _## You should have received a copy of the GNU General Public License
17   _## along with this program; if not, write to the Free Software
18   _## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19   _## MA 02110-1301 USA
20   _##
21   _##########################################################################*/

22
23 package org.snmp4j.agent.agentx.subagent;
24
25 import java.io.IOException JavaDoc;
26
27 import org.snmp4j.agent.agentx.*;
28 import org.snmp4j.agent.mo.*;
29 import org.snmp4j.log.LogAdapter;
30 import org.snmp4j.log.LogFactory;
31 import org.snmp4j.smi.*;
32 import org.snmp4j.agent.agentx.subagent.index.AnyNewIndexOID;
33 import org.snmp4j.agent.agentx.subagent.index.NewIndexOID;
34
35 /**
36  * The <code>AgentXSharedMOTableSupport</code> provides helper functions for
37  * shared table implementations to register rows and indexes at a master agent.
38  *
39  * @author Frank Fock
40  * @version 1.0
41  */

42 public class AgentXSharedMOTableSupport implements MOTableRowListener {
43
44   private static final LogAdapter LOGGER =
45       LogFactory.getLogger(AgentXSharedMOTableSupport.class);
46
47   public static final int INDEX_MODE_ALLOCATE = AgentXProtocol.FLAG_ALLOCATE_INDEX;
48   public static final int INDEX_MODE_ANY_INDEX = AgentXProtocol.FLAG_ANY_INDEX;
49   public static final int INDEX_MODE_NEW_INDEX = AgentXProtocol.FLAG_NEW_INDEX;
50
51   private AgentX agentX;
52   private AgentXSession session;
53   private OctetString context;
54   private byte priority = AgentXProtocol.DEFAULT_PRIORITY;
55   private byte indexMode = INDEX_MODE_ALLOCATE;
56
57   /**
58    * Creates a shared table support object for a AgentX connection, session,
59    * and context.
60    *
61    * @param agentX
62    * an AgentX connection.
63    * @param session
64    * an AgentXSession session (does not need to be open at creation time).
65    * @param context
66    * a context ("" by default).
67    */

68   public AgentXSharedMOTableSupport(AgentX agentX, AgentXSession session,
69                                     OctetString context) {
70     this.agentX = agentX;
71     this.session = session;
72     this.context = context;
73   }
74
75   /**
76    * Creates a shared table support object for a AgentX connection, session,
77    * and context.
78    *
79    * @param agentX
80    * an AgentX connection.
81    * @param session
82    * an AgentXSession session (does not need to be open at creation time).
83    * @param context
84    * a context ("" by default).
85    * @param priority
86    * the registration priority used for this shared table support.
87    * @param indexAllocationMode
88    * the index allocation mode to be used as default for this shared table.
89    */

90   public AgentXSharedMOTableSupport(AgentX agentX, AgentXSession session,
91                                     OctetString context,
92                                     byte priority, byte indexAllocationMode) {
93     this(agentX, session, context);
94     this.priority = priority;
95     this.indexMode = indexAllocationMode;
96   }
97
98   /**
99    * Process shared table row events. If index mode is
100    * {@link #INDEX_MODE_ALLOCATE} this method will do nothing if the associated
101    * AgentX session is closed. For other index modes, the event's veto status
102    * will be set to the AgentX error {@link AgentXProtocol#AGENTX_NOT_OPEN}.
103    * <p>
104    * If the index OID of a created row has zero length then, depending on the
105    * current index mode, a new or any new index is allocated at the master
106    * agent.
107    *
108    * @param event
109    * a <code>MOTableRowEvent</code> indicating a row change in an AgentX
110    * shared table.
111    */

112   public void rowChanged(MOTableRowEvent event) {
113     if ((indexMode == INDEX_MODE_ALLOCATE) && getSession().isClosed()) {
114       // ignore closed session for allocation mode
115
if (LOGGER.isInfoEnabled()) {
116         LOGGER.info("Row event " + event +
117                     " ignored, because session to master agent is closed: " +
118                     getSession());
119       }
120       return;
121     }
122     switch (event.getType()) {
123       case MOTableRowEvent.CREATE: {
124         OID index2Allocate = event.getRow().getIndex();
125         int status =
126             allocateIndex(context, event.getTable().getIndexDef(),
127                           (event.getRow().getIndex().size() == 0) ?
128                           indexMode : 0,
129                           index2Allocate);
130         if (status != AgentXProtocol.AGENTX_SUCCESS) {
131           event.setVetoStatus(status);
132         }
133         break;
134       }
135       case MOTableRowEvent.ADD: {
136         int status = registerRow(event.getTable(), event.getRow());
137         if (status != AgentXProtocol.AGENTX_SUCCESS) {
138           event.setVetoStatus(status);
139         }
140         break;
141       }
142       case MOTableRowEvent.DELETE: {
143         int status = unregisterRow(event.getTable(), event.getRow());
144         if (status != AgentXProtocol.AGENTX_SUCCESS) {
145           event.setVetoStatus(status);
146         }
147         else {
148           OID index2Deallocate = event.getRow().getIndex();
149           status = deallocateIndex(context, event.getTable().getIndexDef(),
150                                    index2Deallocate);
151         }
152         break;
153       }
154       default: {
155         if (LOGGER.isDebugEnabled()) {
156           LOGGER.debug("Ignored AgentX shared table event "+event);
157         }
158       }
159     }
160   }
161
162   /**
163    * Allocate a new or any index at the master agent and return its value in
164    * <code>allocateIndex</code>.
165    *
166    * @param context
167    * the context for which to allocate the index. Specify an empty
168    * <code>OctetString</code> for the default context.
169    * @param indexDef
170    * the index definition with OID values for sub-index definitions.
171    * @param indexAllocationMode
172    * one of {@link AgentXProtocol#FLAG_ANY_INDEX},
173    * {@link AgentXProtocol#FLAG_NEW_INDEX}, or 0 (if index value is supplied
174    * by <code>allocateIndex</code>).
175    * @param allocatedIndex
176    * the index value to allocate or if <code>indexAllocationMode</code> is
177    * not zero then an (arbitrary non-null OID) which returns the allocated
178    * new index value. If <code>allocateIndex</code> is an instance of
179    * {@link AnyNewIndexOID} or {@link NewIndexOID} the index value of the
180    * row will be replaced by a globally unique index value allocated by the
181    * master agent. The caller is responsible for changing the rows index
182    * in the table model of the shared table.
183    * @return
184    * {@link AgentXProtocol#AGENTX_SUCCESS} if the index could be allocated
185    * or an AgentX protocol error code if allocation failed and
186    * <code>allocateIndex</code> is not altered.
187    */

188   public int allocateIndex(OctetString context,
189                            MOTableIndex indexDef,
190                            byte indexAllocationMode,
191                            OID allocatedIndex) {
192     VariableBinding[] vbs = new VariableBinding[indexDef.size()];
193     Variable[] indexValues;
194     if (allocatedIndex instanceof AnyNewIndexOID) {
195       indexAllocationMode = INDEX_MODE_ANY_INDEX;
196     }
197     else if (allocatedIndex instanceof NewIndexOID) {
198       indexAllocationMode = INDEX_MODE_NEW_INDEX;
199     }
200     if (indexAllocationMode == 0) {
201       indexValues = indexDef.getIndexValues(allocatedIndex);
202     }
203     else {
204       indexValues = new Variable[indexDef.size()];
205       for (int i=0; i<indexDef.size(); i++) {
206         MOTableSubIndex subIndex = indexDef.getIndex(i);
207         indexValues[i] =
208             AbstractVariable.createFromSyntax(subIndex.getSmiSyntax());
209       }
210     }
211     for (int i=0; i<indexDef.size(); i++) {
212       MOTableSubIndex subIndex = indexDef.getIndex(i);
213       OID oid = subIndex.getOid();
214       if (oid == null) {
215         throw new IllegalArgumentException JavaDoc("Sub-index "+i+" has no OID");
216       }
217       vbs[i] = new VariableBinding();
218       vbs[i].setOid(oid);
219       vbs[i].setVariable(indexValues[i]);
220     }
221     AgentXIndexAllocatePDU pdu = new AgentXIndexAllocatePDU(context, vbs);
222     if (indexAllocationMode != 0) {
223       pdu.addFlag(indexAllocationMode);
224     }
225     pdu.setSessionAttributes(session);
226     try {
227       AgentXResponseEvent response =
228           agentX.send(pdu, session.createAgentXTarget(),
229                       session.getPeer().getTransport());
230       if (response.getResponse() != null) {
231         AgentXResponsePDU resp = response.getResponse();
232         if (resp.getErrorStatus() == AgentXProtocol.AGENTX_SUCCESS) {
233           OID index =
234               indexDef.getIndexOID(getVariables(resp.getVariableBindings()));
235           allocatedIndex.setValue(index.getValue());
236           if (LOGGER.isDebugEnabled()) {
237             LOGGER.debug("Allocated index "+allocatedIndex+" for context "+
238                          context+" and index definition "+indexDef);
239           }
240         }
241         else {
242           if (LOGGER.isDebugEnabled()) {
243             LOGGER.debug("Index allocation failed for context "+
244                          context+" and index definition "+indexDef+
245                          " with value "+allocatedIndex);
246           }
247         }
248         return resp.getErrorStatus();
249       }
250       else {
251         return AgentXProtocol.AGENTX_TIMEOUT;
252       }
253     }
254     catch (IOException JavaDoc ex) {
255       LOGGER.error("Failed to allocate index "+indexDef+" at "+session, ex);
256     }
257     return AgentXProtocol.AGENTX_DISCONNECT;
258   }
259
260   /**
261    * Deallocate an index at the master agent.
262    *
263    * @param context
264    * the context for which to allocate the index. Specify an empty
265    * <code>OctetString</code> for the default context.
266    * @param indexDef
267    * the index definition with OID values for sub-index definitions.
268    * @param allocatedIndex
269    * the index value of the previously allocated index.
270    * @return
271    * {@link AgentXProtocol#AGENTX_SUCCESS} if the index could be deallocated
272    * or an AgentX protocol error code if deallocation failed.
273    */

274   public int deallocateIndex(OctetString context,
275                              MOTableIndex indexDef,
276                              OID allocatedIndex) {
277     VariableBinding[] vbs = new VariableBinding[indexDef.size()];
278     Variable[] indexValues = indexDef.getIndexValues(allocatedIndex);
279     for (int i=0; i<indexDef.size(); i++) {
280       vbs[i] = new VariableBinding();
281       MOTableSubIndex subIndex = indexDef.getIndex(i);
282       OID oid = subIndex.getOid();
283       if (oid == null) {
284         throw new IllegalArgumentException JavaDoc("Sub-index "+i+" has no OID");
285       }
286       vbs[i].setOid(oid);
287       vbs[i].setVariable(indexValues[i]);
288     }
289     AgentXIndexDeallocatePDU pdu = new AgentXIndexDeallocatePDU(context, vbs);
290     pdu.setSessionAttributes(session);
291     try {
292       AgentXResponseEvent response =
293           agentX.send(pdu, session.createAgentXTarget(),
294                       session.getPeer().getTransport());
295       if (response.getResponse() != null) {
296         AgentXResponsePDU resp = response.getResponse();
297         return resp.getErrorStatus();
298       }
299       else {
300         return AgentXProtocol.AGENTX_TIMEOUT;
301       }
302     }
303     catch (IOException JavaDoc ex) {
304       LOGGER.error("Failed to deallocate index "+indexDef+" at "+session, ex);
305     }
306     return AgentXProtocol.AGENTX_DISCONNECT;
307   }
308
309
310   public int registerRow(MOTable table, MOTableRow row2Register) {
311     OID subtree = new OID(table.getOID());
312     subtree.append(table.getColumn(0).getColumnID());
313     subtree.append(row2Register.getIndex());
314     AgentXRegisterPDU pdu =
315         new AgentXRegisterPDU(context, subtree, priority,
316                               (byte)(table.getOID().size()+1),
317                               table.getColumn(table.getColumnCount()-1).
318                               getColumnID());
319     if (table.getColumnCount() == 1) {
320       pdu.addFlag(AgentXProtocol.FLAG_INSTANCE_REGISTRATION);
321     }
322     pdu.setSessionAttributes(session);
323     try {
324       AgentXResponseEvent resp =
325           agentX.send(pdu, session.createAgentXTarget(),
326                       session.getPeer().getTransport());
327       if (resp.getResponse() == null) {
328         return AgentXProtocol.AGENTX_TIMEOUT;
329       }
330       else if (resp.getResponse().getErrorStatus() !=
331                AgentXProtocol.AGENTX_SUCCESS) {
332         return resp.getResponse().getErrorStatus();
333       }
334     }
335     catch (IOException JavaDoc ex) {
336       LOGGER.error("Failed to send AgentXRegister pdu "+pdu+" to "+session+
337                    " because: "+ex.getMessage(), ex);
338       return AgentXProtocol.AGENTX_DISCONNECT;
339     }
340     return AgentXProtocol.AGENTX_SUCCESS;
341   }
342
343   public int unregisterRow(MOTable table, MOTableRow row2Unregister) {
344     OID subtree = new OID(table.getOID());
345     subtree.append(table.getColumn(0).getColumnID());
346     subtree.append(row2Unregister.getIndex());
347     AgentXUnregisterPDU pdu =
348         new AgentXUnregisterPDU(context, subtree, priority,
349                                 (byte)(table.getOID().size()+1),
350                                 table.getColumn(table.getColumnCount()-1).
351                                 getColumnID());
352     pdu.setSessionAttributes(session);
353     try {
354       AgentXResponseEvent resp =
355           agentX.send(pdu, session.createAgentXTarget(),
356                       session.getPeer().getTransport());
357       if (resp.getResponse() == null) {
358         return AgentXProtocol.AGENTX_TIMEOUT;
359       }
360       else if (resp.getResponse().getErrorStatus() !=
361                AgentXProtocol.AGENTX_SUCCESS) {
362         return resp.getResponse().getErrorStatus();
363       }
364     }
365     catch (IOException JavaDoc ex) {
366       LOGGER.error("Failed to send AgentXRegister pdu "+pdu+" to "+session+
367                    " because: "+ex.getMessage(), ex);
368       return AgentXProtocol.AGENTX_DISCONNECT;
369     }
370     return AgentXProtocol.AGENTX_SUCCESS;
371   }
372
373   private static Variable[] getVariables(VariableBinding[] vbs) {
374     Variable[] variables = new Variable[vbs.length];
375     for (int i=0; i<vbs.length; i++) {
376       variables[i] = vbs[i].getVariable();
377     }
378     return variables;
379   }
380
381   public void setPriority(byte priority) {
382     this.priority = priority;
383   }
384
385   /**
386    * Sets the AgentX session to be used for this shared table support.
387    * @param session
388    * an <code>AgentXSession</code> instance.
389    */

390   public void setSession(AgentXSession session) {
391     this.session = session;
392   }
393
394   /**
395    * Sets the index mode to be used by this shared table support object.
396    * {@link #INDEX_MODE_ALLOCATE} simply allocates index values at the master
397    * agent, whereas {@link #INDEX_MODE_ANY_INDEX} fetches any currently
398    * unique index value from the master agent for a new row and
399    * {@link #INDEX_MODE_NEW_INDEX} fetches a new index (never used before by
400    * the master).
401    * @param indexMode
402    * an index mode to be used for shared tables supported by this object.
403    */

404   public void setIndexMode(byte indexMode) {
405     this.indexMode = indexMode;
406   }
407
408   public void setContext(OctetString context) {
409     this.context = context;
410   }
411
412   public byte getPriority() {
413     return priority;
414   }
415
416   /**
417    * Gets the AgentX session used by this shared table support object.
418    * @return
419    * an <code>AgentXSession</code> instance or <code>null</code> if there
420    * is no connection/session established with the master agent.
421    */

422   public AgentXSession getSession() {
423     return session;
424   }
425
426   public byte getIndexMode() {
427     return indexMode;
428   }
429
430   public OctetString getContext() {
431     return context;
432   }
433
434   public AgentX getAgentX() {
435     return agentX;
436   }
437
438 }
439
Popular Tags